/*****************************************************************************
*  Copyright Statement:
*  --------------------
*  This software is protected by Copyright and the information contained
*  herein is confidential. The software may not be copied and the information
*  contained herein may not be used or disclosed except with the written
*  permission of MediaTek Inc. (C) 2005
*
*  BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
*  THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
*  RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
*  AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
*  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
*  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
*  NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
*  SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
*  SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
*  THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
*  NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
*  SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
*
*  BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
*  LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
*  AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
*  OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
*  MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
*  THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
*  WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
*  LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
*  RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
*  THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
*
*****************************************************************************/

/*******************************************************************************
 * Filename:
 * ---------
 *   cam_msg_handler.c
 *
 * Project:
 * --------
 *   Maui
 *
 * Description:
 * ------------
 *   This file includes message handle functions of image module.
 *
 * Author:
 * -------
 * -------
 *
 *==============================================================================
 *             HISTORY
 * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *------------------------------------------------------------------------------
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 * removed!
 * removed!
 * removed!
 *
 *------------------------------------------------------------------------------
 * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!!
 *==============================================================================
 *******************************************************************************/
#ifndef MED_NOT_PRESENT

/*==== INCLUDES =========*/
/* system includes */
#include "kal_release.h"
#include "kal_trace.h"
#include "stack_common.h"
#include "stack_msgs.h"
#include "app_ltlcom.h" /* Task message communiction */
#include "syscomp_config.h"
#include "task_config.h"        /* Task creation */
#include "app_buff_alloc.h"     /* Declaration of buffer management API */
#include "stacklib.h"   /* Basic type for dll, evshed, stacktimer */
#include "event_shed.h" /* Event scheduler */
#include "stack_timer.h"        /* Stack timer */

/* global includes */
#include "l1audio.h"
#include "device.h"
#include "resource_audio.h"
#include "nvram_enums.h"
#include "nvram_struct.h"
#include "nvram_user_defs.h"
#include "nvram_data_items.h"
#include "custom_nvram_editor_data_item.h"
#include "lcd_if.h"
#include "lcd_sw_inc.h"
#include "fat_fs.h"
#include "custom_equipment.h"
#include "jpeg.h"
#include "iul_color_convert.h"
#ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__
#include "FSAL.h"
#endif

#if defined(ISP_SUPPORT)
#include "isp_if.h"
#include "ae_awb.h"
#include "visual_comm.h"
    #if defined(DRV_IDP_OLD_DESIGN)
    #include "image_effect.h"
    #include "img_comm.h"
    #endif
#elif defined(__DIRECT_SENSOR_SUPPORT__)
    #include "camera_if.h"
#endif /* ISP_SUPPORT */

/* local includes */
#include "med_global.h"
#include "med_main.h"
#include "aud_defs.h"
#include "med_struct.h"
#include "med_api.h"
#include "med_context.h"
#include "med_smalloc.h"
#include "med_utility.h"
#include "cam_main.h"
#include "img_main.h"
#include "cam_v_main.h"

/* XENON_FLASHLIGHT */
#if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
#include "uem_context.h"
#include "uem_utility.h"
#include "isp_flashlight.h"
#endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

#if defined(__CAM_AUTO_FOCUS__) 
#include "af.h"
#endif

#if defined(__MED_VID_ENC_MOD__) || defined(__MED_MJPG_ENC_MOD__)
#include "vid_main.h"
#endif

#ifdef MP4_DECODE
#include "med_c_main.h"
#include "med_c_struct.h"
#endif /* MP4_DECODE */

#ifdef __MED_TVO_MOD__
#include "tv_out.h"
#include "tvo_main.h"
#endif /* __MED_TVO_MOD__ */

#ifdef __CAM_TRACE_ON__
#include "med_trc.h"
#endif

#include "dcmgr.h"

#if defined(BARCODE_DECODER_SCANBUY_QRDM) || defined(BARCODE_DECODER_SCANBUY_DM)
#include "sc_2dDecoder.h"
#elif defined(BARCODE_DECODER_GMEDIA_DM) || defined(BARCODE_DECODER_GMEDIA_QRDM)
#include "gmedia_dec.h"
#endif

#if MT6238_SERIES
#include "idp_cal.h"
#include "idp_camera_preview.h"
#include "jpeg_codec.h"
#include "jpeg_capture_wrapper.h"
JPEG_CODEC_STATE_ENUM _jpeg_state = 0;
#endif

#if defined(__MED_CAM_FD_SUPPORT__)
#include "idp_cal.h"
#include "camera_post_process_v2.h"
#endif

#ifdef BCR_SUPPORT_PENPOWER
#include "penpower_bcr_engine.h"
#endif /*BCR_SUPPORT_PENPOWER*/

#ifdef __MED_CAM_MOD__

/**************************************************************************************************
 * External Functions Declaration
 **************************************************************************************************/
extern kal_uint32 INT_SwitchStackToRun(void *stack_start, kal_uint32 stack_size, kal_func_ptr func, kal_uint32 argc, ...);
#if defined(__MM_DEBUG_MEASURE__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#else /* defined(__MM_DEBUG_MEASURE__) */
#define MED_CAM_START_LOGGING(_symbol_)
#define MED_CAM_STOP_LOGGING(_symbol_)
#endif /* defined(__MM_DEBUG_MEASURE__) */

#if defined(__MED_MEM_DEBUG_ON__) && defined(__MTK_TARGET__) && !defined(WIN32)
kal_uint32 g_u32_cam_start_time;
kal_uint32 g_u32_cam_end_time;
kal_uint32 g_u32_cam_duration;
#define MED_CAM_GET_START_TIME(_trace_) \
        do{\
            kal_get_time(&g_u32_cam_start_time);\
        }while(0)
#define MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(_trace_)\
        do{\
            kal_get_time(&g_u32_cam_end_time);\
            g_u32_cam_duration = kal_ticks_to_milli_secs(g_u32_cam_end_time - g_u32_cam_start_time);\
            kal_trace(TRACE_GROUP_2,_trace_, g_u32_cam_duration,__LINE__);\
        }while(0)
#else /* defined(__MED_MEM_DEBUG_ON__) && defined(__MTK_TARGET__) && !defined(WIN32) */
#define MED_CAM_GET_START_TIME(_trace_)
#define MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(_trace_) 
#endif /* defined(__MED_MEM_DEBUG_ON__) && defined(__MTK_TARGET__) && !defined(WIN32) */

/**************************************************************************************************
 * MACRO Definition
 **************************************************************************************************/
#define CAM_FREE_CAPTURE_BUFFER()do{\
                                    if (cam_context_p->capture_buffer_p)\
                                    {\
                                        med_free_ext_mem((void**)&cam_context_p->capture_buffer_p);\
                                        cam_context_p->capture_buffer_p = NULL;\
                                    }\
                                }while(0)
#define CAM_FREE_INT_BUFFER()   do{\
                                    if (cam_context_p->intmem_start_address) \
                                    {\
                                        med_free_int_mem((void**)&cam_context_p->intmem_start_address);\
                                        cam_context_p->intmem_start_address = NULL;\
                                    }\
                                }while(0)
                                
#define CAM_FREE_EXT_BUFFER()   do{\
                                    if (cam_context_p->extmem_start_address)\
                                    {\
                                        med_free_ext_mem((void**)&cam_context_p->extmem_start_address);\
                                        cam_context_p->extmem_start_address = NULL;\
                                    }\
                                }while(0)
                                
#define CAM_FREE_BARCODE_BUFFER()  do{\
                                        if(cam_context_p->barcode_buffer_address)\
                                        {\
                                            med_free_ext_mem((void**)&cam_context_p->barcode_buffer_address);\
                                            cam_context_p->barcode_buffer_address=NULL;\
                                        }\
                                        if(cam_context_p->dummy_barcode_buffer_address) \
                                        {\
                                            med_free_ext_mem((void**)&cam_context_p->dummy_barcode_buffer_address);\
                                            cam_context_p->dummy_barcode_buffer_address = NULL;\
                                        }\
                                    }while(0)

#define CAM_CAPTURE_TIMEOUT_DURATION (5000)
#define CAM_FD_PROCESS_TIMEOUT_DURATION (20)
/**************************************************************************************************
 * Static Variables
 **************************************************************************************************/
#if defined(ISP_SUPPORT) || defined(__DIRECT_SENSOR_SUPPORT__)
kal_int32 cam_capture_mem[2] = {MAX_CAM_CAP_INT_MEM_SIZE, MAX_CAM_CAP_EXT_MEM_SIZE};
kal_int32 cam_preview_mem[2] = {MAX_CAM_PREVIEW_INT_MEM_SIZE, MAX_CAM_PREVIEW_EXT_MEM_SIZE};
#endif

#if defined(ISP_SUPPORT) 
kal_uint8 cam_rotate_map[CAM_NO_OF_IMAGE_ROTATE] =
{
    IMAGE_NORMAL,
    IMAGE_NORMAL,
    IMAGE_HV_MIRROR,
    IMAGE_NORMAL,
    IMAGE_H_MIRROR,
    IMAGE_NORMAL,
    IMAGE_V_MIRROR,
    IMAGE_NORMAL
};
#endif /* defined(ISP_SUPPORT) */

#if defined (ISP_SUPPORT) || defined(__DIRECT_SENSOR_SUPPORT__)

#if MT6238_SERIES
    camera_capture_jpeg_struct capture_isp_param;
    camera_preview_process_struct preview_param;
#else
    jpeg_encode_process_struct jpg_encode;
#endif

    camera_capture_mem_struct capture_mem_param;
#endif


/**************************************************************************************************
 * Static Functions Declaration
 **************************************************************************************************/
static void cam_release_af_lens_if_not_continuous_shot(void);
#if defined(__MED_CAM_FD_SUPPORT__)
static void cam_fd_process(void* args);
#endif
#if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
static void cam_xenon_status_check(void *args);
kal_int32 cam_turn_on_xenonflash(void);
kal_int32 cam_turn_off_xenonflash(void);
#endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

/*==== FUNCTIONS ===========*/
#if defined (ISP_SUPPORT)
static void cam_check_sensor_id(void);
#endif
extern kal_bool mmi_em_profiling_camera_is_app_capture_profiling(void);

#ifdef MBM_IMIBASE_SUPPORT
extern kal_uint8 g_mbm_cam_data_req_flag ;
extern kal_uint8 g_mbm_cam_is_work_flag ;
extern kal_uint8 g_mbm_cam_is_init_flag ;
#endif  /*MBM_IMIBASE_SUPPORT*/

/*****************************************************************************
 * FUNCTION
 *  cam_open_image_file
 * DESCRIPTION
 *  This function is to open image file for capture.
 * PARAMETERS
 *  file_name       [?]
 *  buffer_size     [IN]
 * RETURNS
 *  void
 *****************************************************************************/
kal_int32 cam_open_image_file(kal_wchar *file_name, kal_uint32 buffer_size)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 result;
#ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__
    FSAL_Status fsal_ret;
    kal_int32 fsal_error;
#endif    
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* check if the format valid */
    /* open the file */
#ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__    
    if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        fsal_ret = FSAL_Open(&cam_context_p->fsal_file, (void*)file_name, FSAL_WRITE);
        if (fsal_ret != FSAL_OK)
        {
            fsal_error = FSAL_GetLastError(&cam_context_p->fsal_file);
            if (fsal_error == FS_DRIVE_NOT_FOUND)
            {
                return MED_RES_NO_DISC;
            }
            else if (fsal_error == FS_DISK_FULL)
            {
                return MED_RES_DISC_FULL;
            }
            else
            {
                return MED_RES_OPEN_FILE_FAIL;
            }
        }
        CAM_FREE_CAPTURE_BUFFER();
        cam_context_p->capture_buffer_p = (kal_uint32) med_alloc_ext_mem(buffer_size);

        if (cam_context_p->capture_buffer_p == NULL)
        {
            FSAL_Close(&cam_context_p->fsal_file);
            FS_Delete((kal_wchar*) file_name);
            return MED_RES_MEM_INSUFFICIENT;
        }
        else
        {
            cam_context_p->file_name_p = (kal_wchar*) file_name;
        }
            
        FSAL_SetBuffer(&cam_context_p->fsal_file, MAX_JPEG_ENCODE_MARGIN_LEN, (kal_uint8 *)cam_context_p->capture_buffer_p);
        return MED_RES_OK;
    }
    else
#endif
    {
        cam_context_p->file_handle = FS_Open((kal_wchar*) file_name, FS_CREATE | FS_READ_WRITE);

        if (cam_context_p->file_handle >= 0)
        {
            /* Check free memory space first */
            if ((result = med_check_disc_space(file_name, CAPTURE_MEM_MARGIN)) != MED_RES_OK)
            {
                FS_Close(cam_context_p->file_handle);
                FS_Delete((kal_wchar*) file_name);
                return result;
            }
            /* to release the memory allocated in MED_MODE_BUFFER mode */
            CAM_FREE_CAPTURE_BUFFER();
            cam_context_p->capture_buffer_p = (kal_uint32) med_alloc_ext_mem(buffer_size);
            if (cam_context_p->capture_buffer_p == NULL)
            {
                FS_Close(cam_context_p->file_handle);
                FS_Delete((kal_wchar*) file_name);
                return MED_RES_MEM_INSUFFICIENT;
            }
            else
            {
                cam_context_p->file_name_p = (kal_wchar*) file_name;
                return MED_RES_OK;
            }
        }
        else if (cam_context_p->file_handle == FS_WRITE_PROTECTION)
        {
            return MED_RES_WRITE_PROTECTION;
        }
        else if ((cam_context_p->file_handle == FS_ROOT_DIR_FULL) || (cam_context_p->file_handle == FS_DISK_FULL))
        {
            return MED_RES_DISC_FULL;
        }
        else
        {
            return MED_RES_OPEN_FILE_FAIL;
        }
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_close_image_file
 * DESCRIPTION
 *  This function is to close image file for capture.
 * PARAMETERS
 *  size        [IN]
 * RETURNS
 *  void
 *****************************************************************************/
kal_int32 cam_close_image_file(kal_uint32 size)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 result;
#ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__
    kal_int32 fsal_error;
    FSAL_Status fsal_ret;
#endif
    kal_uint32 len;
    kal_int32 res = MED_RES_OK;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__    
    if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        result = (kal_int32)size;
        fsal_error = FSAL_GetLastError(&cam_context_p->fsal_file);       
        fsal_ret = FSAL_Close(&cam_context_p->fsal_file);
        
        if (!(result > 0) || fsal_ret == FSAL_CLOSE_ERROR)
        {
            FS_Delete((kal_wchar*) cam_context_p->file_name_p);

            if (fsal_ret == FSAL_CLOSE_ERROR)
            {
                fsal_error = FSAL_GetLastError(&cam_context_p->fsal_file);
                result = JPEG_SW_ENC_WRITE_FILE_FAILED;
            }
            
            if (result == JPEG_SW_ENC_OUT_OF_OUTPUT_BUFFER)
            {
                res = MED_RES_ERROR;
            }
            else if (result == JPEG_SW_ENC_WRITE_FILE_FAILED)
            {
                if (fsal_error == FS_DRIVE_NOT_FOUND)
                {
                    res = MED_RES_NO_DISC;
                }
                else if (fsal_error == FS_DISK_FULL)
                {
                    res = MED_RES_DISC_FULL;
                }
                else
                {
                    res = MED_RES_OPEN_FILE_FAIL;
                }
            }
            else
            {
                res = MED_RES_OPEN_FILE_FAIL;
            }
        }
    }
    else
#endif
    {
        if (size > 0)
        {
            MED_CAM_GET_START_TIME(CAM_WRITE_TO_FILE_DURATION);
            MED_CAM_START_LOGGING("CFS");
            result = FS_Write(cam_context_p->file_handle, (void*)cam_context_p->capture_buffer_p, size, &len);
            MED_CAM_STOP_LOGGING("CFS");

            MED_CAM_START_LOGGING("CFC");
            FS_Close(cam_context_p->file_handle);
            MED_CAM_STOP_LOGGING("CFC");
            MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_WRITE_TO_FILE_DURATION);

            if (result != FS_NO_ERROR)
            {
                CAM_CLOSE_IMAGE_RESULT_TRACE(result);
                FS_Delete((kal_wchar*) cam_context_p->file_name_p);
                if (result == FS_DRIVE_NOT_FOUND)
                {
                    res = MED_RES_NO_DISC;
                }
                else if (result == FS_DISK_FULL)
                {
                    res = MED_RES_DISC_FULL;
                }
                else
                {
                    res = MED_RES_OPEN_FILE_FAIL;
                }
            }
            else if (size != len)
            {
                FS_Delete((kal_wchar*) cam_context_p->file_name_p);
                res = MED_RES_DISC_FULL;
            }
        }
        else
        {
            /* Close and delete the file */
            FS_Close(cam_context_p->file_handle);
            FS_Delete((kal_wchar*) cam_context_p->file_name_p);
            res = MED_RES_DISC_FULL;
        }
    }
    /* to release the memory allocated in MED_MODE_BUFFER mode */
    if (cam_context_p->media_mode == MED_MODE_FILE)
        CAM_FREE_CAPTURE_BUFFER();

    return res;
}


/*****************************************************************************
 * FUNCTION
 *  cam_set_flash
 * DESCRIPTION
 *  This function is to set the flash.
 * PARAMETERS
 *  flash_mode      [IN]
 *  kal_int16 value(?)
 * RETURNS
 *  void
 *****************************************************************************/
kal_int16 cam_set_flash(kal_int16 flash_mode)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    return MED_RES_OK;
}


/*****************************************************************************
 * FUNCTION
 *  cam_set_flash_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera set flash request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_set_flash_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_set_flash_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_set_flash_req_struct*) ilm_ptr->local_para_ptr;

    cam_set_flash(req_p->flash_mode);

}


/*****************************************************************************
 * FUNCTION
 *  cam_set_sensor_id
 * DESCRIPTION
 *  
 * PARAMETERS
 *  
 * RETURNS
 *  void
 *****************************************************************************/
#if defined (ISP_SUPPORT)
void cam_set_sensor_id(kal_int16 cam_id, kal_uint32* sensor_id_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint32 sensor_id = 0;
    
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    sensor_id = *sensor_id_p;
    
    set_image_sensor_id(cam_id, sensor_id);
    if (cam_id == CAM_MAIN_CAMERA)
    {
        cam_context_p->main_sensor_id = sensor_id;
    }
    else if (cam_id == CAM_SUB_CAMERA)
    {
        cam_context_p->sub_sensor_id = sensor_id;
    }

#if defined(DUAL_CAMERA_SUPPORT)
    if (cam_id == CAM_MAIN_CAMERA)
    {
        cam_send_msg_to_nvram(CAM_NVRAM_READ, NVRAM_EF_CAMERA_SUB_SENSOR_ID_LID, 0, 0);
    }
    else if (cam_id == CAM_SUB_CAMERA)
    {
        cam_check_sensor_id();
    }
#else
    cam_check_sensor_id();
#endif
}


/*****************************************************************************
 * FUNCTION
 *  cam_detect_sensor_id_req_hdlr
 * DESCRIPTION
 *  This function is to handle power up request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_detect_sensor_id_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_detect_sensor_id_req_struct *req_p;
    kal_uint32 sensor_id = 0;
    
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_IDLE))
    {
        req_p = (media_cam_detect_sensor_id_req_struct*) ilm_ptr->local_para_ptr;
        cam_context_p->cam_id = req_p->cam_id;
    #if defined(DUAL_CAMERA_SUPPORT)
        if (cam_context_p->main_sensor_id == NULL || cam_context_p->sub_sensor_id == NULL)
    #else
        if (cam_context_p->main_sensor_id == NULL)
    #endif
        {
            cam_send_msg_to_nvram(CAM_NVRAM_READ, NVRAM_EF_CAMERA_MAIN_SENSOR_ID_LID, 0, 0);
            CAM_ENTER_STATE(CAM_DETECT_SENSOR);
        }
        else
        {
            if (cam_context_p->cam_id == CAM_MAIN_CAMERA)
            {
                sensor_id = cam_context_p->main_sensor_id;
            }
            else
            {
                sensor_id = cam_context_p->sub_sensor_id;
            }
            set_image_sensor_id(cam_context_p->cam_id, sensor_id);
            set_isp_oper_camera_id(cam_context_p->cam_id);
            cam_set_result(MED_RES_OK);
            CAM_SET_EVENT(CAM_EVT_BLOCK);
        }
    }
    else if (CAM_IN_STATE(CAM_DETECT_SENSOR))
    {
        cam_set_result(MED_RES_BUSY);
        CAM_SET_EVENT(CAM_EVT_BLOCK);  
    }
    else if (cam_context_p->cam_id == CAM_MAIN_CAMERA && 
        cam_context_p->main_sensor_id != NULL && 
        cam_context_p->main_sensor_id != 0xffffffff)
    {
        set_image_sensor_id(cam_context_p->cam_id, cam_context_p->main_sensor_id);
        set_isp_oper_camera_id(cam_context_p->cam_id);
        cam_set_result(MED_RES_OK);
        CAM_SET_EVENT(CAM_EVT_BLOCK);         
    }
    else if (cam_context_p->cam_id == CAM_SUB_CAMERA && 
        cam_context_p->sub_sensor_id != NULL && 
        cam_context_p->sub_sensor_id != 0xffffffff)
    {
        set_image_sensor_id(cam_context_p->cam_id, cam_context_p->sub_sensor_id);
        set_isp_oper_camera_id(cam_context_p->cam_id);
        cam_set_result(MED_RES_OK);
        CAM_SET_EVENT(CAM_EVT_BLOCK);        
    }
    else
    {
        ASSERT(0);
    }       
}


/*****************************************************************************
 * FUNCTION
 *  cam_detect_sensor_id_req_hdlr
 * DESCRIPTION
 *  
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_detect_sensor_id_cnf_hdlr(void)
{
    CAM_ENTER_STATE(CAM_IDLE);

    set_isp_oper_camera_id(cam_context_p->cam_id);  
    CAM_SET_EVENT(CAM_EVT_BLOCK);
}



/*****************************************************************************
 * FUNCTION
 *  cam_check_sensor_id
 * DESCRIPTION
 *  This function is to handle power up request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
static void cam_check_sensor_id(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_uint32 main_sensor_id;
#if defined(DUAL_CAMERA_SUPPORT)
    kal_uint32 sub_sensor_id;
#endif    
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (cam_context_p->main_sensor_id == 0xffffffff)
    {
        open_isp();
        set_isp_oper_camera_id(CAM_MAIN_CAMERA);
        main_sensor_id = detect_connected_sensor_id(CAM_MAIN_CAMERA);
        set_image_sensor_id(CAM_MAIN_CAMERA, main_sensor_id);   
        cam_context_p->main_sensor_id = main_sensor_id;
    #if defined(DUAL_CAMERA_SUPPORT)
        set_isp_oper_camera_id(CAM_SUB_CAMERA);
        sub_sensor_id = detect_connected_sensor_id(CAM_SUB_CAMERA);
        set_image_sensor_id(CAM_SUB_CAMERA, sub_sensor_id);
        cam_context_p->sub_sensor_id = sub_sensor_id;
    #endif
        close_isp();
        cam_send_msg_to_nvram(
            CAM_NVRAM_WRITE, 
            NVRAM_EF_CAMERA_MAIN_SENSOR_ID_LID, 
            &main_sensor_id, 
            sizeof(main_sensor_id));
    }
#if defined(DUAL_CAMERA_SUPPORT)    
    else if (cam_context_p->sub_sensor_id == 0xffffffff)
    {
        open_isp();
        set_isp_oper_camera_id(CAM_MAIN_CAMERA);
        main_sensor_id = detect_connected_sensor_id(CAM_MAIN_CAMERA);
        set_image_sensor_id(CAM_MAIN_CAMERA, main_sensor_id);   
        cam_context_p->main_sensor_id = main_sensor_id;

        set_isp_oper_camera_id(CAM_SUB_CAMERA);
        sub_sensor_id = detect_connected_sensor_id(CAM_SUB_CAMERA);
        set_image_sensor_id(CAM_SUB_CAMERA, sub_sensor_id);
        cam_context_p->sub_sensor_id = sub_sensor_id;
        
        close_isp();   
        cam_send_msg_to_nvram(
            CAM_NVRAM_WRITE, 
            NVRAM_EF_CAMERA_MAIN_SENSOR_ID_LID, 
            &main_sensor_id, 
            sizeof(main_sensor_id));
    }    
#endif
    else
    {      
        cam_detect_sensor_id_cnf_hdlr();
    }   
}


/*****************************************************************************
 * FUNCTION
 *  cam_check_sensor_id
 * DESCRIPTION
 *  This function is to handle power up request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_sensor_id_nvram_write_cnf(kal_uint8 cam_id)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
#if defined(DUAL_CAMERA_SUPPORT)
    kal_uint32 sub_sensor_id;
#endif

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if defined(DUAL_CAMERA_SUPPORT) 
    if (cam_id == CAM_MAIN_CAMERA)
    {
        sub_sensor_id = cam_context_p->sub_sensor_id;
        cam_send_msg_to_nvram(CAM_NVRAM_WRITE, NVRAM_EF_CAMERA_SUB_SENSOR_ID_LID, &sub_sensor_id, sizeof(sub_sensor_id));
    }
    else
    {
        cam_detect_sensor_id_cnf_hdlr();
    }
#else
    cam_detect_sensor_id_cnf_hdlr();
#endif
}
#endif /* defined (ISP_SUPPORT) */


#if defined (ISP_SUPPORT) || defined(__DIRECT_SENSOR_SUPPORT__)

#ifdef MBM_IMIBASE_SUPPORT
extern camera_preview_process_struct g_mbm_preview_param; // used global variable to avoid memory leak.
#endif  /*MBM_IMIBASE_SUPPORT*/

/*****************************************************************************
 * FUNCTION
 *  cam_release_memory
 * DESCRIPTION
 *  This function is to release cam related memory.
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void cam_release_memory(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (cam_context_p->int_frame_buffer_p)
    {
        med_free_int_mem((void **)&cam_context_p->int_frame_buffer_p);
    }
    if (cam_context_p->ext_frame_buffer_p)
    {
        med_free_ext_mem((void **)&cam_context_p->ext_frame_buffer_p);
    }
    if (cam_context_p->intmem_start_address)
    {
        med_free_int_mem((void **)&cam_context_p->intmem_start_address);
    }
#if !MT6225_SERIES
    if (cam_context_p->extmem_start_address)
    {
        med_free_ext_mem((void **)&cam_context_p->extmem_start_address);
    }
#endif    
#if defined(__MED_CAM_FD_SUPPORT__)
    if (cam_context_p->extmem_fd_start_address)
    {
        med_free_ext_mem((void **)&cam_context_p->extmem_fd_start_address);
    }
#endif

#if MT6225_SERIES
    if (cam_context_p->y_address)
    {
        cam_context_p->y_address = NULL;
    }
    if (cam_context_p->u_address)
    {
        cam_context_p->u_address = NULL;
    }
    if (cam_context_p->v_address)
    {
        cam_context_p->v_address = NULL;
    }
    #ifdef EXIF_SUPPORT
    if (cam_context_p->exif_thumbnail_address)
    {
        med_free_ext_mem((void **)&cam_context_p->exif_thumbnail_address);
    }
    if (cam_context_p->exif_work_address)
    {
        med_free_ext_mem((void **)&cam_context_p->exif_work_address);
    }
    #endif
#endif /* MT6225_SERIES */

#if MT6238_SERIES
    if (cam_context_p->raw_image_buffer_address)
    {
        med_free_ext_mem((void **)&cam_context_p->raw_image_buffer_address);
        cam_context_p->raw_image_buffer_address = NULL;
    }
#endif

#if defined(__CAM_DZ_NEED_EXTRA_MEM__)
    if (cam_context_p->dz_extmem_address)
    {
        med_free_ext_mem((void **)&cam_context_p->dz_extmem_address);
        cam_context_p->dz_extmem_address = NULL;
        cam_context_p->dz_extmem_size = 0;
    }
#endif /* defined(__CAM_DZ_NEED_EXTRA_MEM__) */    

#ifdef MBM_IMIBASE_SUPPORT
    if (g_mbm_cam_is_work_flag)
    {
        //med_free_int_mem((void **)&g_miipts_preview_param.intmem_start_address);
        med_free_ext_mem((void **)&g_mbm_preview_param.intmem_start_address);
        g_mbm_preview_param.intmem_size = 0;

        med_free_ext_mem((void **)&g_mbm_preview_param.y_address1);
        g_mbm_preview_param.y_address1 = 0;
        med_free_ext_mem((void **)&g_mbm_preview_param.y_address2);
        g_mbm_preview_param.y_address2 = 0;

        g_mbm_cam_is_work_flag = 0;
    }
#endif  /*MBM_IMIBASE_SUPPORT*/
}


/*****************************************************************************
 * FUNCTION
 *  cam_power_up_req_hdlr
 * DESCRIPTION
 *  This function is to handle power up request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_power_up_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_power_up_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_power_up_req_struct*) ilm_ptr->local_para_ptr;

    cam_context_p->seq_num = req_p->seq_num;
    cam_context_p->cam_id = req_p->cam_id;

#if defined(ISP_SUPPORT)
    set_isp_oper_camera_id(cam_context_p->cam_id);
#endif
    if (CAM_IN_STATE(CAM_IDLE))
    {
    #if defined(__MTK_TARGET__)
        #if defined(ISP_SUPPORT)
        init_isp_if();
        #elif defined(__DIRECT_SENSOR_SUPPORT__)
        camera_init();
        #endif
    #endif
        CAM_ENTER_STATE(CAM_READY);
        cam_send_ready_ind(MED_RES_OK);
    }
    else if (CAM_IN_STATE(CAM_READY))
    {
        cam_send_ready_ind(MED_RES_OK);
    }
    CAM_SET_EVENT(CAM_EVT_POWER_UP);
}


/*****************************************************************************
 * FUNCTION
 *  cam_power_down_req_hdlr
 * DESCRIPTION
 *  This function is to handle power down request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_power_down_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_power_down_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_power_down_req_struct*) ilm_ptr->local_para_ptr;

    if (!CAM_IN_STATE(CAM_IDLE))
    {
    #ifdef __MTK_TARGET__
    #ifdef __MED_VID_ENC_MOD__
        ASSERT((!VID_IN_STATE(VID_RECORD)) && (!VID_IN_STATE(VID_RECORD_PAUSED))) if (VID_IN_STATE(VID_PREVIEW))
        {
            exit_mpeg4_encode_process();
            vid_release_memory();
            VID_ENTER_STATE(VID_IDLE);
        }
    #endif /* __MED_VID_ENC_MOD__ */
        if (CAM_IN_STATE(CAM_PREVIEW))
        {
            exit_camera_preview_process();
            /* copy int_frame_buffer data to MMI buffer for displaying correct */
            if (cam_context_p->int_frame_buffer_p)
            {
                memcpy(
                    (kal_uint8*) cam_context_p->frame_buffer_p,
                    (kal_uint8*) cam_context_p->int_frame_buffer_p,
                    cam_context_p->frame_buffer_size);
            }
        }

    #if MT6238_SERIES && defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
        /**
         * if stop preview by MMI in panorama capture mode & captured number < CAM_PANO_MAX_SHOT_NUM , we need to help release af len
         */
        if (cam_context_p->special_capture_mode == CAM_CAPTURE_PANORAMA_SHOT_MODE && cam_context_p->captured_number < CAM_PANO_MAX_SHOT_NUM)
        {
            cam_release_af_lens_if_not_continuous_shot();
        }
    #endif
    #if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
        if (cam_context_p->xenon_flash_status != CAM_XENON_FLASH_OFF)
            med_stop_timer(CAM_XENON_FLASH_CHECK_TIMER);
    #endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

    #if defined(__MED_CAM_FD_SUPPORT__)
        // Stop fd timer if not in stopped state
        if (CAM_FD_IN_STATE(CAM_FD_STATE_STARTED))
            med_stop_timer(CAM_FD_CAL_TIMER);
    #endif
        
        #if defined(ISP_SUPPORT)
        power_off_isp();
        #elif defined(__DIRECT_SENSOR_SUPPORT__)
        camera_exit();
        #endif
        /* to release the memory allocated in MED_MODE_BUFFER mode */
        CAM_FREE_CAPTURE_BUFFER();
        cam_release_memory();
    #endif /* __MTK_TARGET__ */
        CAM_ENTER_STATE(CAM_IDLE);
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_preview_callback
 * DESCRIPTION
 *  This function is to handle camera preview callback.
 * PARAMETERS
 *  cause       [IN]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void cam_preview_callback(kal_uint8 cause)
{
#ifdef MP4_DECODE
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_hp_send_event_ind(CAM_EVT_PREVIEW, cause);
#else /* MP4_DECODE */
    cam_send_event_ind(CAM_EVT_PREVIEW, cause);
#endif /* MP4_DECODE */
}


/*****************************************************************************
 * FUNCTION
 *  cam_focus_callback
 * DESCRIPTION
 *  This function is to handle camera focus callback.
 * PARAMETERS
 *  cause       [IN]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void cam_focus_callback(kal_uint8 cause)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_send_event_ind(CAM_EVT_AUTOFOCUS, cause);
}


/*****************************************************************************
 * FUNCTION
 *  cam_get_preview_frame_rate
 * DESCRIPTION
 *  This function is to convert preview frame rate.
 * PARAMETERS
 *  frame_rate      [IN]
 * RETURNS
 *  kal_uint8
 *****************************************************************************/
kal_uint8 cam_get_preview_frame_rate(kal_int16 frame_rate)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    switch (frame_rate)
    {
        case CAMERA_PERVIEW_FRAME_RATE:
            return 30;
        case VIDEO_PERVIEW_FRAME_RATE:
            return 15;
        default:
            return 15;
    }
}

#if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
#define XENON_FLASH_STATE_IN(STATE) (cam_context_p->xenon_flash_status==STATE)

/*****************************************************************************
 * FUNCTION
 *  cam_xenon_status_check
 * DESCRIPTION
 *  This function is to check current xenon flash light status
 * PARAMETERS
 *  args     [IN]  we do not use it.
 * RETURNS
 *  void
 *****************************************************************************/
static void cam_xenon_status_check(void *args)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    xenon_para_struct xenon_para;
    xenon_info_struct *xenon_info_p;
    uem_bmt_struct bmt_status;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_PREVIEW)||CAM_IN_STATE(CAM_READY)) 
    {
        uem_get_bat_status(&bmt_status);

        if (bmt_status.volt == 0)
            xenon_para.voltage = 3700;
        else
            xenon_para.voltage = bmt_status.volt/1000;

        if (xenon_para.voltage  < 3400)
        {
            cam_turn_off_xenonflash();
            cam_send_xenon_flash_status_ind(CAM_XENON_FLASH_LOW_BATTERY);
            return;
        }                

        xenon_info_p = isp_xenon_flashlight_ready_check(&xenon_para);
        switch (xenon_info_p->retcode)
        {
            case XENON_RETCODE_READY:
                if (XENON_FLASH_STATE_IN(CAM_XENON_FLASH_CHARGING))
                {
                    cam_context_p->xenon_flash_status = CAM_XENON_FLASH_READY;
                    cam_send_xenon_flash_status_ind(cam_context_p->xenon_flash_status);
                }
                med_start_timer(CAM_XENON_FLASH_CHECK_TIMER , xenon_info_p->ready_polling_period, cam_xenon_status_check, 0);
                break;
            case XENON_RETCODE_CHARGE_STOP:
            case XENON_RETCODE_CHARGE_TIMEOUT:
                //**< do nothing 
                break;
            case XENON_RETCODE_NOT_READY:
                if (XENON_FLASH_STATE_IN(CAM_XENON_FLASH_CHARGING))
                {
                    if (cam_context_p->xenon_max_charge_duty == 0)
                    {
                        cam_turn_off_xenonflash();
                        cam_send_xenon_flash_status_ind(CAM_XENON_FLASH_TIMEOUT);
                    }
                    else
                    {
                        if (cam_context_p->xenon_max_charge_duty < xenon_info_p->ready_polling_period)
                            cam_context_p->xenon_max_charge_duty = 0;
                        else 
                            cam_context_p->xenon_max_charge_duty -= xenon_info_p->ready_polling_period;
                        med_start_timer(CAM_XENON_FLASH_CHECK_TIMER , xenon_info_p->ready_polling_period, cam_xenon_status_check, 0);
                    }
                }
                else if(XENON_FLASH_STATE_IN(CAM_XENON_FLASH_READY))
                {
                    ASSERT(0);
                }                
                break;
        }
    }
    else
        ASSERT(0);
}


/*****************************************************************************
 * FUNCTION
 *  cam_turn_on_xenonflash
 * DESCRIPTION
 *  This function is to turn on/off xenon flash light.
 * PARAMETERS
 *  voltage        [IN]  Current voltage
 * RETURNS
 *  kal_int32     
 *****************************************************************************/
kal_int32 cam_turn_on_xenonflash(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    xenon_para_struct xenon_para;
    xenon_info_struct *xenon_info_p;
    kal_int32 ret_code = MED_RES_OK;
    uem_bmt_struct bmt_status;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    uem_get_bat_status(&bmt_status);

    if (bmt_status.volt == 0)
        xenon_para.voltage = 3700;
    else
        xenon_para.voltage = bmt_status.volt/1000;

    if (xenon_para.voltage < 3400)
    {
        cam_turn_off_xenonflash();
        cam_send_xenon_flash_status_ind(CAM_XENON_FLASH_LOW_BATTERY);
        return ret_code;
    }
    
    xenon_info_p = isp_xenon_flashlight_charge(KAL_TRUE,&xenon_para);
    switch (xenon_info_p->retcode)
    {
        case XENON_RETCODE_READY:            
            cam_context_p->xenon_flash_status = CAM_XENON_FLASH_READY;
            cam_send_xenon_flash_status_ind(cam_context_p->xenon_flash_status);
            med_start_timer(CAM_XENON_FLASH_CHECK_TIMER , xenon_info_p->ready_polling_period, cam_xenon_status_check, 0);
            break;
        case XENON_RETCODE_CHARGE_STOP:
            //* do nothing
            break;
        case XENON_RETCODE_NOT_READY:
            cam_context_p->xenon_flash_status = CAM_XENON_FLASH_CHARGING;
            cam_send_xenon_flash_status_ind(cam_context_p->xenon_flash_status);
            cam_context_p->xenon_max_charge_duty = xenon_info_p->max_charge_duty - xenon_info_p->ready_polling_period;
            med_start_timer(CAM_XENON_FLASH_CHECK_TIMER , xenon_info_p->ready_polling_period, cam_xenon_status_check, 0);
            break;                
    }
    return ret_code;
}


/*****************************************************************************
 * FUNCTION
 *  cam_turn_off_xenonflash
 * DESCRIPTION
 *  This function is to turn off xenon flash light.
 * PARAMETERS
 *  voltage        [IN]  Current voltage
 * RETURNS
 *  kal_int32    
 *****************************************************************************/
kal_int32 cam_turn_off_xenonflash(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    xenon_para_struct xenon_para;
    xenon_info_struct *xenon_info_p;
    kal_int32 ret_code = MED_RES_OK;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    xenon_info_p = isp_xenon_flashlight_charge(KAL_FALSE,&xenon_para);
    cam_context_p->xenon_flash_status = CAM_XENON_FLASH_OFF;
    camera_operation_setting((kal_uint8) CAM_FLASH_MODE, (kal_uint16) CAM_FLASH_OFF);
    med_stop_timer(CAM_XENON_FLASH_CHECK_TIMER);
    return ret_code;
}
#endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */


/*****************************************************************************
 * FUNCTION
 *  cam_preview_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera preview request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_preview_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_preview_req_struct *req_p;
#if !(MT6238_SERIES)
    camera_preview_process_struct preview_param;
#endif
    kal_uint32 result_code = MED_RES_OK;
   
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if defined(ISP_SUPPORT)
    {
    #if defined(DRV_IDP_OLD_DESIGN)
        MMDI_SCENERIO_ID old_app;

        if(KAL_TRUE != idp_register_app(SCENARIO_CAMERA_PREVIEW_ID,&old_app))
        {
            cam_set_result(MED_RES_BUSY);
            CAM_SET_EVENT(CAM_EVT_PREVIEW);
            return;
        }
    #else
        if(KAL_TRUE == idp_camera_preview_is_in_use())
        {
            cam_set_result(MED_RES_BUSY);
            CAM_SET_EVENT(CAM_EVT_PREVIEW);
            return;
        }
    #endif
    }
#endif

    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_READY))
    {
        req_p = (media_cam_preview_req_struct*) ilm_ptr->local_para_ptr;

    #if defined(__DIRECT_SENSOR_SUPPORT__)
        cam_context_p->lcd_start_x = preview_param.lcm_start_x = req_p->lcd_start_x;
        cam_context_p->lcd_start_y = preview_param.lcm_start_y = req_p->lcd_start_y;
        cam_context_p->lcd_end_x = preview_param.lcm_end_x = req_p->lcd_end_x;
        cam_context_p->lcd_end_y = preview_param.lcm_end_y = req_p->lcd_end_y;

        cam_context_p->zoom_factor = preview_param.zoom_factor = (kal_uint8) req_p->zoom_factor;
        cam_context_p->image_mirror = preview_param.image_mirror = req_p->rotate;
        cam_context_p->contrast_level = preview_param.contrast_level = req_p->contrast;
        cam_context_p->brightness_level = preview_param.brightness_level = req_p->brightness;
        cam_context_p->saturation_value = preview_param.saturation_value = req_p->saturation;
        cam_context_p->wb_mode = preview_param.wb_mode = req_p->WB;
        cam_context_p->ev_value = preview_param.exposure_value = preview_param.ev_value = req_p->exposure;
        cam_context_p->banding_freq = preview_param.banding_freq = req_p->banding_freq;
        cam_context_p->image_effect = preview_param.image_effect = req_p->effect;
        cam_context_p->night_mode = preview_param.night_mode = req_p->night_mode;
        cam_context_p->hue_value = preview_param.hue_value = req_p->hue;
    #else
        cam_context_p->lcd_update = preview_param.lcd_update = req_p->lcd_update;
        cam_context_p->lcd_id = preview_param.lcd_id = req_p->lcd_id;
        cam_context_p->lcd_start_x = preview_param.lcm_start_x = req_p->lcd_start_x;
        cam_context_p->lcd_start_y = preview_param.lcm_start_y = req_p->lcd_start_y;
        cam_context_p->lcd_end_x = preview_param.lcm_end_x = req_p->lcd_end_x;
        cam_context_p->lcd_end_y = preview_param.lcm_end_y = req_p->lcd_end_y;
        cam_context_p->roi_offset_x = preview_param.roi_offset_x = req_p->roi_offset_x;
        cam_context_p->roi_offset_y = preview_param.roi_offset_y = req_p->roi_offset_y;
        cam_context_p->update_layer = preview_param.update_layer = req_p->update_layer;
        cam_context_p->hw_update_layer = preview_param.hw_update_layer = req_p->hw_update_layer;

        cam_context_p->preview_offset_x = preview_param.preview_offset_x = req_p->preview_offset_x;
        cam_context_p->preview_offset_y = preview_param.preview_offset_y = req_p->preview_offset_y;

        cam_context_p->intmem_start_address = preview_param.intmem_start_address = 
                                            (kal_uint32) med_alloc_int_mem(cam_preview_mem[0]);
        cam_context_p->intmem_size = preview_param.intmem_size = (kal_uint32) cam_preview_mem[0];
        cam_context_p->extmem_start_address = preview_param.extmem_start_address = 0;
        cam_context_p->extmem_size = preview_param.extmem_size = 0;
        cam_context_p->preview_width = preview_param.target_width = req_p->preview_width;
        cam_context_p->preview_height = preview_param.target_height = req_p->preview_height;

        /* initialize face detection */
    #if defined(__MED_CAM_FD_SUPPORT__)
        cam_context_p->fd_enable = preview_param.fd_enable = req_p->fd_enable;
        CAM_FD_ENTER_STATE(CAM_FD_STATE_STOPPED);
        if (cam_context_p->fd_enable == KAL_TRUE)
        {        
            cam_context_p->extmem_fd_start_address = preview_param.extmem_fd_start_address = (kal_uint32) med_alloc_ext_mem_cacheable(MAX_CAM_FD_EXT_MEM_SIZE);
            cam_context_p->extmem_fd_size = preview_param.extmem_fd_size = MAX_CAM_FD_EXT_MEM_SIZE;
            cam_context_p->extmem_start_address = preview_param.extmem_start_address = (kal_uint32) med_alloc_ext_mem(MAX_CAM_FD_IMAGE_BUFFER_SIZE*3);
            cam_context_p->extmem_size = preview_param.extmem_size = MAX_CAM_FD_IMAGE_BUFFER_SIZE*3;

            ASSERT (cam_context_p->extmem_start_address!=0 && cam_context_p->extmem_fd_start_address!=0);
        }
        else
        {
            cam_context_p->extmem_fd_start_address = preview_param.extmem_fd_start_address = 0;
            cam_context_p->extmem_fd_size = preview_param.extmem_fd_size = 0;
        }    
    #endif /* defined(__MED_CAM_FD_SUPPORT__) */

        /* use internal memory for preview buffer if enough */
        if (((req_p->image_buffer_size * 2) + MEM_OVERHEAD) < med_int_left_size())
        {
            CAM_BUFFER_TRACE(1);
            /* internal memory enough for double buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                                               preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            cam_context_p->int_frame_buffer_p = preview_param.frame_buffer_address =
                                                (kal_uint32) med_alloc_int_mem(preview_param.frame_buffer_size * 2);
            preview_param.frame_buffer_address1 = preview_param.frame_buffer_address + preview_param.frame_buffer_size;
            cam_context_p->ext_frame_buffer_p = 0;
        }
        else if (req_p->image_buffer_size + MEM_OVERHEAD < med_int_left_size())
        {
            CAM_BUFFER_TRACE(2);
            /* internal memory enough for single buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                                               preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            /* one internal buffer */
            cam_context_p->int_frame_buffer_p = preview_param.frame_buffer_address =
                                                (kal_uint32) med_alloc_int_mem(preview_param.frame_buffer_size);
            /* one external buffer */
            preview_param.frame_buffer_address1 = cam_context_p->frame_buffer_p;
            cam_context_p->ext_frame_buffer_p = 0;
        }
        else if (req_p->image_buffer_size + MEM_OVERHEAD < med_ext_left_size())
        {
            CAM_BUFFER_TRACE(3);
            /* internal memory enough for single buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                                               preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            /* one external buffer given from MMI */
            preview_param.frame_buffer_address = cam_context_p->frame_buffer_p;
            /* one more external buffer */
        #ifdef MT6235
            if (cam_context_p->frame_buffer_size %16 != 0)
            {
                cam_context_p->frame_buffer_size = ((cam_context_p->frame_buffer_size + 15) >> 4) << 4;
                preview_param.frame_buffer_size = cam_context_p->frame_buffer_size;
            }
        #endif /* MT6235 */
            cam_context_p->ext_frame_buffer_p = preview_param.frame_buffer_address1 =
                                                (kal_uint32) med_alloc_ext_mem_framebuffer(preview_param.frame_buffer_size);
            cam_context_p->int_frame_buffer_p = 0;
        }
        else
        {
            CAM_BUFFER_TRACE(4);
            /* use single external buffer from MMI */
            cam_context_p->frame_buffer_p = preview_param.frame_buffer_address1 = preview_param.frame_buffer_address =
                                            (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = preview_param.frame_buffer_size1 = preview_param.frame_buffer_size =
                                               req_p->image_buffer_size;
            cam_context_p->int_frame_buffer_p = 0;
            cam_context_p->ext_frame_buffer_p = 0;
        }
    #if MT6238_SERIES
        kal_mem_set((void*)preview_param.frame_buffer_address, 0, preview_param.frame_buffer_size);
        kal_mem_set((void*)preview_param.frame_buffer_address1, 0, preview_param.frame_buffer_size);
    #endif        
            
        cam_context_p->image_mirror = preview_param.image_mirror = cam_rotate_map[req_p->rotate];
        cam_context_p->ev_value = preview_param.ev_value = req_p->exposure;
        cam_context_p->wb_mode = preview_param.wb_mode = req_p->WB;
        cam_context_p->contrast_level = preview_param.contrast_level = req_p->contrast;
        cam_context_p->image_effect = preview_param.image_effect = req_p->effect;

    #if MT6238_SERIES
        cam_context_p->saturation_value = preview_param.saturation_level = req_p->saturation;
        cam_context_p->sharpness_level = preview_param.sharpness_level = req_p->sharpness_level;
        cam_context_p->binning_mode = preview_param.binning_mode = req_p->binning_mode;
        cam_context_p->continue_capture = KAL_FALSE;
        cam_context_p->zoom_factor = preview_param.zoom_step = req_p->zoom_factor;
        cam_context_p->max_zoom_factor = preview_param.max_zoom_factor = req_p->max_zoom_factor;
        cam_context_p->total_zoom_step = preview_param.total_zoom_step = req_p->total_zoom_step;
        cam_context_p->raw_capture_enable = KAL_FALSE;
        cam_context_p->raw_image_buffer_address = NULL;
    #else
        cam_context_p->zoom_factor = preview_param.zoom_factor = (kal_uint8) req_p->zoom_factor;
        cam_context_p->camera_offset_x=preview_param.camera_offset_x=req_p->camera_offset_x;
        cam_context_p->camera_offset_y=preview_param.camera_offset_y=req_p->camera_offset_y;
        cam_context_p->continue_capture = preview_param.continue_capture = req_p->continue_capture;
        cam_context_p->hue_value = preview_param.hue_value = req_p->hue;
        cam_context_p->night_mode = preview_param.night_mode = req_p->night_mode;
        cam_context_p->brightness_level = preview_param.brightness_level = req_p->brightness;
        cam_context_p->saturation_value = preview_param.saturation_value = req_p->saturation;
    #endif /* MT6238_SERIES */

        cam_context_p->banding_freq = preview_param.banding_freq = req_p->banding_freq;
        cam_context_p->lcd_rotate = req_p->lcd_rotate;
        cam_context_p->frame_rate = preview_param.frame_rate = cam_get_preview_frame_rate(req_p->frame_rate);
        preview_param.rotate_value = (kal_uint8) req_p->lcd_rotate;

        /* LCD Setting */
        cam_context_p->roi_background_color = preview_param.roi_background_color = req_p->roi_background_color;

        /* AF */
    #if defined(__CAM_AUTO_FOCUS__) &&  !MT6238_SERIES
        cam_context_p->af_zone0_x = preview_param.af_zone0_x = req_p->af_zone0_x;
        cam_context_p->af_zone0_y = preview_param.af_zone0_y = req_p->af_zone0_y;
        cam_context_p->af_zone1_x = preview_param.af_zone1_x = req_p->af_zone1_x;
        cam_context_p->af_zone1_y = preview_param.af_zone1_y = req_p->af_zone1_y;
        cam_context_p->af_zone2_x = preview_param.af_zone2_x = req_p->af_zone2_x;
        cam_context_p->af_zone2_y = preview_param.af_zone2_y = req_p->af_zone2_y;
        cam_context_p->af_zone3_x = preview_param.af_zone3_x = req_p->af_zone3_x;
        cam_context_p->af_zone3_y = preview_param.af_zone3_y = req_p->af_zone3_y;
        cam_context_p->af_zone4_x = preview_param.af_zone4_x = req_p->af_zone4_x;
        cam_context_p->af_zone4_y = preview_param.af_zone4_y = req_p->af_zone4_y;
    #endif /* defined(__CAM_AUTO_FOCUS__) &&  !MT6238_SERIES */

    #if (MT6228_SERIES || MT6238_SERIES)
        #ifdef __MED_TVO_MOD__
            tvo_context_p->tv_output_mode = req_p->tv_output_mode;
            tvo_context_p->tv_output = preview_param.tv_output = req_p->tv_output;
            tvo_context_p->tv_output_width = preview_param.tv_output_width = req_p->tv_output_width;
            tvo_context_p->tv_output_height = preview_param.tv_output_height = req_p->tv_output_height;
            tvo_context_p->tv_output_offset_x = preview_param.tv_output_offset_x = req_p->tv_output_offset_x;
            tvo_context_p->tv_output_offset_y = preview_param.tv_output_offset_y = req_p->tv_output_offset_y;
            tvo_context_p->tv_output_buffer_size = preview_param.tv_output_buffer_size = req_p->tv_output_buffer_size;
            tvo_context_p->tv_output_buffer1_address = preview_param.tv_output_buffer1_address = req_p->tv_output_buffer1_address;
            tvo_context_p->tv_output_buffer2_address = preview_param.tv_output_buffer2_address = req_p->tv_output_buffer2_address;
            tvo_context_p->tv_rotate_buffer1_address = preview_param.tv_rotate_buffer1_address = req_p->tv_rotate_buffer1_address;
            tvo_context_p->tv_rotate_buffer2_address = preview_param.tv_rotate_buffer2_address = req_p->tv_rotate_buffer2_address;
        #endif /* __MED_TVO_MOD__ */

        /* ISP Setting */
        cam_context_p->ae_metering_mode = preview_param.ae_metering_mode = req_p->ae_metering_mode;
        cam_context_p->prev_dsc_mode = req_p->dsc_mode;
        cam_context_p->dsc_mode = preview_param.dsc_mode = req_p->dsc_mode;

        cam_context_p->flash_mode = preview_param.flash_mode = req_p->flash_mode;
        /* IPP Setting */
        cam_context_p->image_pitch_mode = preview_param.image_pitch_mode = req_p->image_pitch_mode;
        cam_context_p->image_data_format = preview_param.image_data_format = req_p->image_data_format;

    #if MT6228_SERIES
        cam_context_p->af_metering_mode = preview_param.af_metering_mode = req_p->af_metering_mode;
        cam_context_p->af_mode = preview_param.af_mode = req_p->af_mode;
        cam_context_p->tv_setting = preview_param.tv_setting = req_p->tv_setting;
        cam_context_p->av_setting = preview_param.av_setting = req_p->av_setting;
        cam_context_p->iso_setting = preview_param.iso_setting = req_p->iso_setting;

        if (cam_context_p->dsc_mode != CAM_NIGHTSCENE && cam_context_p->iso_setting != CAM_ISO_AUTO)
        {
            if (cam_context_p->dsc_mode == CAM_FLOWER)
            {
                cam_context_p->af_mode = preview_param.af_mode = CAM_AF_MACRO_MODE;
            }
            else
                cam_context_p->af_mode = preview_param.af_mode = CAM_AF_AUTO_MODE;    
            cam_context_p->dsc_mode = preview_param.dsc_mode = CAM_ISO_MODE;
        }
        else if (cam_context_p->dsc_mode!= CAM_FLOWER)
        {
            cam_context_p->af_mode = preview_param.af_mode = CAM_AF_AUTO_MODE;
        }
        cam_context_p->image_pitch_bytes = preview_param.image_pitch_bytes = req_p->image_pitch_bytes;
        cam_context_p->overlay_frame_mode = preview_param.overlay_frame_mode = req_p->overlay_frame_mode;
        cam_context_p->overlay_color_depth = preview_param.overlay_color_depth = req_p->overlay_color_depth;
        cam_context_p->overlay_frame_source_key = preview_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
        cam_context_p->overlay_frame_width = preview_param.overlay_frame_width = req_p->overlay_frame_width;
        cam_context_p->overlay_frame_height = preview_param.overlay_frame_height = req_p->overlay_frame_height;
        cam_context_p->overlay_frame_buffer_address = preview_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;
    #elif MT6238_SERIES
        cam_context_p->af_metering_mode = preview_param.af_operation_mode = req_p->af_operation_mode;
        cam_context_p->af_mode = preview_param.af_range = req_p->af_range;
        cam_context_p->rot_angle = preview_param.rot_angle = req_p->rot_angle;
        cam_context_p->preview_rotate_value = preview_param.preview_rotate_value = req_p->preview_rotate_value;
        cam_context_p->image_bg_image_width = preview_param.image_bg_image_width = req_p->image_bg_image_width;

        cam_context_p->overlay_frame_mode = preview_param.overlay_frame_mode = req_p->overlay_frame_mode;
        cam_context_p->overlay_color_depth = preview_param.overlay_color_depth = req_p->overlay_color_depth;
        cam_context_p->overlay_frame_source_key = preview_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
        cam_context_p->overlay_frame_width = preview_param.overlay_frame_width = req_p->overlay_frame_width;
        cam_context_p->overlay_frame_height = preview_param.overlay_frame_height = req_p->overlay_frame_height;
        cam_context_p->overlay_frame_buffer_address = preview_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;
        cam_context_p->overlay_palette_size = preview_param.overlay_palette_size = req_p->overlay_palette_size;
        cam_context_p->overlay_palette_addr = preview_param.overlay_palette_addr = (kal_uint32)req_p->overlay_palette_addr;
    #endif /* MT6228_SERIES */

    
        /* TV Setting */
    #elif MT6225_SERIES || ( MT6219_SERIES && !defined(MT6219))
        /* ISP Setting */
        cam_context_p->ae_metering_mode = preview_param.ae_metering_mode = req_p->ae_metering_mode;
        cam_context_p->af_metering_mode = preview_param.af_metering_mode = req_p->af_metering_mode;
        cam_context_p->af_mode = preview_param.af_mode = req_p->af_mode;
        cam_context_p->flash_mode = preview_param.flash_mode = req_p->flash_mode;
        cam_context_p->prev_dsc_mode = req_p->dsc_mode;
        cam_context_p->dsc_mode = preview_param.dsc_mode = req_p->dsc_mode;
        cam_context_p->iso_setting = preview_param.iso_setting = req_p->iso_setting;       

        if (cam_context_p->dsc_mode != CAM_NIGHTSCENE && cam_context_p->iso_setting != CAM_ISO_AUTO)
        {
            if (cam_context_p->dsc_mode == CAM_FLOWER)
            {
                cam_context_p->af_mode = preview_param.af_mode = CAM_AF_MACRO_MODE;
            }
            else
            {
                cam_context_p->af_mode = preview_param.af_mode = CAM_AF_AUTO_MODE;
            }
            
            cam_context_p->dsc_mode = preview_param.dsc_mode = CAM_ISO_MODE;
        }
        else if (cam_context_p->dsc_mode!= CAM_FLOWER)
        {
            cam_context_p->af_mode = preview_param.af_mode = CAM_AF_AUTO_MODE;
        }
        
    #endif /* (MT6228_SERIES || MT6238_SERIES) */

        preview_param.cam_preview_cb = cam_preview_callback;

    #ifdef __CAM_AUTO_FOCUS__
        preview_param.cam_focus_cb = cam_focus_callback;
    #endif
    #endif /* defined(__DIRECT_SENSOR_SUPPORT__)*/

        /* initialize xenon flash */
    #if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
        /* initialize off */
        cam_context_p->xenon_flash_status = CAM_XENON_FLASH_OFF;
        if (cam_context_p->flash_mode != CAM_FLASH_OFF)
        {
            result_code = cam_turn_on_xenonflash();
        }
    #endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

    #ifdef __MTK_TARGET__
        if (result_code == MED_RES_OK && camera_preview_process(&preview_param) != KAL_TRUE)
        {
            /* preview failed, free memory and power off camera */
            cam_release_memory();
    
        #if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
            if (cam_context_p->xenon_flash_status != CAM_XENON_FLASH_OFF)
                cam_turn_off_xenonflash();
        #endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

        #if defined(ISP_SUPPORT)
            power_off_isp();
        #elif defined(__DIRECT_SENSOR_SUPPORT)
            camera_exit();
        #endif

            /* to release the memory allocated in MED_MODE_BUFFER mode */
            CAM_FREE_CAPTURE_BUFFER();
            CAM_ENTER_STATE(CAM_IDLE);
            cam_set_result(MED_RES_FAIL);
        }
        else
    #endif /* __MTK_TARGET__ */
        {
        #if defined(__MED_CAM_FD_SUPPORT__)
            if (cam_context_p->fd_enable == KAL_TRUE)
            {
                // enter start state 
                cam_context_p->face_no = 0;
                cam_context_p->fd_time_duration = 0;
                CAM_FD_ENTER_STATE(CAM_FD_STATE_STARTED);
                med_start_timer(CAM_FD_CAL_TIMER, CAM_FD_PROCESS_TIMEOUT_DURATION, cam_fd_process, 0);
            }
        #endif /* defined(__MED_CAM_FD_SUPPORT__) */
        
            CAM_ENTER_STATE(CAM_PREVIEW);
        }
    }
    else
    {
        cam_set_result(MED_RES_BUSY);
    }

    CAM_SET_EVENT(CAM_EVT_PREVIEW);
}


/*****************************************************************************
 * FUNCTION
 *  cam_stop_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera stop request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stop_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_PREVIEW))
    {
    #ifdef __MTK_TARGET__
        exit_camera_preview_process();
    #endif
        /* copy int_frame_buffer data to MMI buffer for displaying correct */
        if (cam_context_p->int_frame_buffer_p)
        {
            memcpy(
                (kal_uint8*) cam_context_p->frame_buffer_p,
                (kal_uint8*) cam_context_p->int_frame_buffer_p,
                cam_context_p->frame_buffer_size);
        }
        cam_release_memory();
        CAM_ENTER_STATE(CAM_READY);

    #if MT6238_SERIES && defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
        /**
         * if stop preview by MMI in panorama capture mode & captured number < CAM_PANO_MAX_SHOT_NUM , we need to help release af len
         */
        if (cam_context_p->special_capture_mode == CAM_CAPTURE_PANORAMA_SHOT_MODE && cam_context_p->captured_number < CAM_PANO_MAX_SHOT_NUM)
        {
            cam_release_af_lens_if_not_continuous_shot();
        }
    #endif
        
    }
    else if (CAM_IN_STATE(CAM_CAPTURE))
    {
    #if MT6238_SERIES
        med_stop_timer(CAM_CAPTURE_TIMEOUT_TIMER);
        stop_camera_capture_process(CAM_CAPTURE_TIME_OUT_STOP);
    #else
        stop_camera_capture_process();
    #endif
        cam_release_memory();
        CAM_ENTER_STATE(CAM_READY);
    }
    
#if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
    if (cam_context_p->xenon_flash_status != CAM_XENON_FLASH_OFF)
        med_stop_timer(CAM_XENON_FLASH_CHECK_TIMER);
#endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

#if defined(__MED_CAM_FD_SUPPORT__)
    // Stop fd timer if not in stopped state
    if (CAM_FD_IN_STATE(CAM_FD_STATE_STARTED))
        med_stop_timer(CAM_FD_CAL_TIMER);
#endif

    
    CAM_SET_EVENT(CAM_EVT_STOP);

}


#if defined(ISP_SUPPORT)
/*****************************************************************************
 * FUNCTION
 *  cam_stop_fast_zoom
 * DESCRIPTION
 *  This function is to stop zoom operation if camera is zooming.
 * PARAMETERS
 *  cause       [IN]
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stop_fast_zoom(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if(cam_context_p->is_fast_zoom == KAL_TRUE)
    {
        isp_fast_zoom_struct zoom_data;
        zoom_data.start = KAL_FALSE;
        
    #if MT6238_SERIES
        camera_fast_zoom_setting(zoom_data);
    #else    
        isp_fast_zoom_setting(zoom_data);
    #endif

        cam_context_p->is_fast_zoom = KAL_FALSE;
    }

    #if defined(__MED_CAM_FD_SUPPORT__)
        // enter start state from zoomin paused.
        if(CAM_FD_IN_STATE(CAM_FD_STATE_ZOOMIN_PAUSED))
        {
            camera_fd_resume();
            CAM_FD_ENTER_STATE(CAM_FD_STATE_STARTED);
        }
    #endif /* defined(__MED_CAM_FD_SUPPORT__) */
}


/*****************************************************************************
 * FUNCTION
 *  cam_start_fast_zoom_req_hdlr
 * DESCRIPTION
 *  This function is to handle the request of starting the camera fast zoom.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_start_fast_zoom_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_start_fast_zoom_req_struct *req_p;
    isp_fast_zoom_struct zoom_data;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_PREVIEW) 
    #if (defined(__MED_VID_ENC_MOD__) || defined(__MED_MJPG_ENC_MOD__))
        || VID_IN_STATE(VID_PREVIEW) || VID_IN_STATE(VID_RECORD) || VID_IN_STATE(VID_RECORD_PAUSED)
    #endif
        )
    {

    #if defined(__MED_CAM_FD_SUPPORT__)
        // enter zoomin_paused state from start state.
        if(CAM_FD_IN_STATE(CAM_FD_STATE_STARTED))
        {
            /* release data from T-DCM */
            camera_fd_pause();
            CAM_FD_ENTER_STATE(CAM_FD_STATE_ZOOMIN_PAUSED);
        }
    #endif /* defined(__MED_CAM_FD_SUPPORT__) */

        req_p = (media_cam_start_fast_zoom_req_struct*) ilm_ptr->local_para_ptr;
        zoom_data.start = KAL_TRUE;

        zoom_data.zoom_in = req_p->zoom_in;
        zoom_data.zoom_limit = req_p->zoom_limit;
        zoom_data.zoom_step = req_p->zoom_step;
        zoom_data.zoom_speed = req_p->zoom_speed;

        #if MT6238_SERIES
        camera_fast_zoom_setting(zoom_data);
        #else    
        isp_fast_zoom_setting(zoom_data);
        #endif
        cam_context_p->is_fast_zoom = KAL_TRUE;
    }
    CAM_SET_EVENT(CAM_EVT_STOP_FAST_ZOOM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_stop_fast_zoom_req_hdlr
 * DESCRIPTION
 *  This function is to handle the request of stopping the camera fast zoom.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stop_fast_zoom_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    isp_fast_zoom_struct zoom_data;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_PREVIEW) 
    #if (defined(__MED_VID_ENC_MOD__) || defined(__MED_MJPG_ENC_MOD__))
        || VID_IN_STATE(VID_PREVIEW) || VID_IN_STATE(VID_RECORD) || VID_IN_STATE(VID_RECORD_PAUSED)
    #endif
        )
    {
        zoom_data.start = KAL_FALSE;
    
        #if MT6238_SERIES
        camera_fast_zoom_setting(zoom_data);
        #else    
        isp_fast_zoom_setting(zoom_data);
        #endif

        cam_context_p->is_fast_zoom = KAL_FALSE;
    
    #if defined(__MED_CAM_FD_SUPPORT__)
        // enter start state from zoomin paused.
        if(CAM_FD_IN_STATE(CAM_FD_STATE_ZOOMIN_PAUSED))
        {
            camera_fd_resume();
            CAM_FD_ENTER_STATE(CAM_FD_STATE_STARTED);
        }
    #endif /* defined(__MED_CAM_FD_SUPPORT__) */
    }
    CAM_SET_EVENT(CAM_EVT_STOP_FAST_ZOOM);
}

/*****************************************************************************
 * FUNCTION
 *  cam_get_focus_zone_req_hdlr
 * DESCRIPTION
 *  This function is to get af zone from drv and return the values to MMI
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_get_focus_zone_req_hdlr(ilm_struct* ilm_ptr)
{
#if MT6238_SERIES
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_af_get_zone_struct *req_p;
    media_cam_af_zone_para_struct *zone_para_p;
    af_zone_para_struct *zone_p;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#ifdef __CAM_AUTO_FOCUS__
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_af_get_zone_struct*) ilm_ptr->local_para_ptr;
    zone_para_p = req_p->zone_para_p;

    if (CAM_IN_STATE(CAM_PREVIEW)
    #if defined(__MED_VID_ENC_MOD__)
        || VID_IN_STATE(VID_PREVIEW)
    #endif
        )
    {
        kal_uint8 i = 0;

    #if defined(__MED_CAM_FD_SUPPORT__)
        if (cam_context_p->fd_enable == KAL_FALSE || (cam_context_p->fd_enable == KAL_TRUE && cam_context_p->face_no == 0))
        {
            set_fd_best_focus_zone(KAL_FALSE, 0);
        }
        else
        {
            set_fd_best_focus_zone(KAL_TRUE, cam_context_p->best_fd_id);
        }
    #endif /* defined(__MED_CAM_FD_SUPPORT__) */
    
        zone_p = get_af_zone_para();
        zone_para_p->af_active_zone = zone_p->af_active_zone;
        for (i=0;i<MEDIA_CAM_AF_ZONE_MAX_NO; i++)
        {
            zone_para_p->af_zone[i].af_zone_h = zone_p->af_zone[i].af_zone_h;
            zone_para_p->af_zone[i].af_zone_w = zone_p->af_zone[i].af_zone_w;
            zone_para_p->af_zone[i].af_zone_x = zone_p->af_zone[i].af_zone_x;
            zone_para_p->af_zone[i].af_zone_y = zone_p->af_zone[i].af_zone_y;
        }
    }
    else
    {
        ASSERT(0);
    }   
    CAM_SET_EVENT(CAM_EVT_GET_FOCUS_ZONE);
#else /* __CAM_AUTO_FOCUS__ */
    ASSERT(0);
#endif /* __CAM_AUTO_FOCUS__ */
#else
    ASSERT(0);
#endif

}


/*****************************************************************************
 * FUNCTION
 *  cam_get_focus_steps_req_hdlr
 * DESCRIPTION
 *  This function is to handle the request of getting the camera fast zoom factor.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_get_focus_steps_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_get_focus_steps_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* isp_fast_zoom_struct zoom_data; */

    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_get_focus_steps_req_struct*) ilm_ptr->local_para_ptr;
#ifdef __CAM_AUTO_FOCUS__
    *(req_p->flag) = get_focus_step(req_p->total_steps, req_p->current_steps);
#endif
    CAM_SET_EVENT(CAM_EVT_GET_FOCUS_STEPS);
}


/*****************************************************************************
 * FUNCTION
 *  cam_get_fast_zoom_factor_req_hdlr
 * DESCRIPTION
 *  This function is to handle the request of getting the camera fast zoom factor.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_get_fast_zoom_factor_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_get_fast_zoom_factor_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* isp_fast_zoom_struct zoom_data; */

    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_get_fast_zoom_factor_req_struct*) ilm_ptr->local_para_ptr;

    #if MT6238_SERIES
        if (req_p->factor!=NULL)
        {
            *(req_p->factor) = get_camera_digital_zoom_factor();
        }
        if (req_p->step!=NULL)
        {
            *(req_p->step) = (kal_uint8)get_camera_digital_zoom_step();
        }
    #else
        if (req_p->factor!=NULL)
        {
            *(req_p->factor) = (kal_uint8)get_isp_digital_zoom_factor();
        }
        if (req_p->step!=NULL)
        {
            *(req_p->step) = 0;
        }
    #endif

    CAM_SET_EVENT(CAM_EVT_GET_FAST_ZOOM_FACTOR);
}
#endif

/*****************************************************************************
 * FUNCTION
 *  cam_img_encode_callback
 * DESCRIPTION
 *  This function is the callback function of image encoding for capture.
 * PARAMETERS
 *  cause       [IN]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_img_encode_callback(kal_uint8 cause)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    img_send_encode_event_ind(cause);
}


#if MT6238_SERIES
kal_int32 cam_jpeg_encoder_callback(JPEG_CODEC_STATE_ENUM state)
{
   _jpeg_state = state;
   return 1;
}
/*****************************************************************************
 * FUNCTION
 *  cam_capture_callback
 * DESCRIPTION
 *  This function is the callback function of capture.
 * PARAMETERS
 *  cause       [IN]
 * RETURNS
 *  void
 *****************************************************************************/
kal_int32 cam_capture_callback(JPEG_CODEC_STATE_ENUM cause)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_release_af_lens_if_not_continuous_shot();
    cam_context_p->captured_number++;
    cam_send_event_ind(CAM_EVT_CAPTURE, (kal_uint8) cause);
    return 1; 
}
#else
/*****************************************************************************
 * FUNCTION
 *  cam_capture_callback
 * DESCRIPTION
 *  This function is the callback function of capture.
 * PARAMETERS
 *  cause       [IN]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_capture_callback(kal_uint8 cause)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_release_af_lens_if_not_continuous_shot();
    jfif_thumbnail_swap((kal_uint32) cam_context_p->capture_buffer_p);
    cam_send_event_ind(CAM_EVT_CAPTURE, (kal_uint8) cause);
}
#endif


#if MT6238_SERIES
void cam_capture_timeout_callback(void *args)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_CAPTURE))
    {
        stop_camera_capture_process(CAM_CAPTURE_TIME_OUT_STOP);
        cam_release_memory();
        CAM_ENTER_STATE(CAM_READY);

        if (cam_context_p->snapshot_number == 1)
        {
            /* if single shot, use blocking mode */
            /* delete opened file handle and delete file */
            cam_close_image_file(0);
            cam_set_result(MED_RES_ERROR);
            CAM_SET_EVENT(CAM_EVT_CAPTURE);
        }
        else if (cam_context_p->special_capture_mode==CAM_CAPTURE_BEST_SHOT_MODE)
        {
            cam_context_p->capture_buffer_p = NULL;
            cam_context_p->best_capture_buffer_p = NULL;

            /* delete opened file handle and delete file */
            cam_close_image_file(0);

            /* if bestshot, use blocking mode */
            cam_set_result(MED_RES_ERROR);
            CAM_SET_EVENT(CAM_EVT_CAPTURE);
        }
        else
        {
            cam_send_capture_event_ind(MED_RES_ERROR, 0);
        }
    }
}
#endif

/*****************************************************************************
 * FUNCTION
 *  cam_capture_from_isp
 * DESCRIPTION
 *  This function is to capture image from ISP to jpeg.
 * PARAMETERS
 *  req_p       [?]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
kal_uint32 cam_capture_from_isp(media_cam_capture_req_struct *req_p)
{
#if defined(ISP_SUPPORT)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
#if !MT6238_SERIES
    camera_capture_jpeg_struct capture_isp_param;
#endif    
    kal_uint32 file_size = 0;
#if MT6225_SERIES
    kal_uint32 img_width ,img_height;
#endif
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    capture_isp_param.target_width = cam_context_p->image_width = req_p->image_width;
    capture_isp_param.target_height = cam_context_p->image_height = req_p->image_height;
    capture_isp_param.intmem_start_address = cam_context_p->intmem_start_address =
        (kal_uint32) med_alloc_int_mem(cam_capture_mem[0]);
    capture_isp_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_capture_mem[0];
    capture_isp_param.extmem_start_address = 0;
    capture_isp_param.extmem_size = 0;

#if MT6238_SERIES
    capture_isp_param.display_width = cam_context_p->preview_width;
    capture_isp_param.display_height = cam_context_p->preview_height;

    capture_isp_param.rot_angle = cam_context_p->rot_angle;
    capture_isp_param.jpeg_enc_quality = (kal_uint8) req_p->image_quality;

    /* it is a special case on 6238 platform, due to captured image size too large in some effect
     * so we workaround on encode quality: 
     * When capturing in effect mode, we use High, Normal, Low only 
     * When capturing in normal mode, we use Fine, High, and Normal */
    if (cam_context_p->image_effect == 0) /* normal mode */ 
    {
        switch (capture_isp_param.jpeg_enc_quality)
        {
            case CAM_JPG_QTY_HIGH:
            case CAM_JPG_QTY_NORMAL:
            case CAM_JPG_QTY_LOW:
                capture_isp_param.jpeg_enc_quality++;
                break;
        }
    }
    
    capture_isp_param.jpeg_enc_yuv_sample_format = IMG_COLOR_FMT_YUV422;
    capture_isp_param.jpeg_enc_dst_buffer_addr = (kal_uint8*)cam_context_p->capture_buffer_p;
    if (req_p->media_mode == MED_MODE_ARRAY)
    {
        capture_isp_param.jpeg_enc_dst_buffer_size = cam_context_p->capture_buffer_size;
    }
    else
    {
        capture_isp_param.jpeg_enc_dst_buffer_size = MAX_CAM_FILE_BUFFER_LEN;
    }    
    capture_isp_param.idp_thumbnail_enable = KAL_TRUE;
    capture_isp_param.jpeg_enc_thumbnail_width = 160;
    capture_isp_param.jpeg_enc_thumbnail_height = 120;

    /* not used: it is for SW Jpeg */
    capture_isp_param.jpeg_enc_y_buffer_addr = 0;
    capture_isp_param.jpeg_enc_u_buffer_addr = 0;
    capture_isp_param.jpeg_enc_v_buffer_addr = 0;
    capture_isp_param.jpeg_enc_y_buffer_size = 0;
    capture_isp_param.jpeg_enc_u_buffer_size = 0;
    capture_isp_param.jpeg_enc_v_buffer_size = 0;    

    /* IPP Setting */
    capture_isp_param.overlay_frame_mode = req_p->overlay_frame_mode;
    capture_isp_param.overlay_color_depth = req_p->overlay_color_depth;
    capture_isp_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
    capture_isp_param.overlay_frame_width = req_p->overlay_frame_width;
    capture_isp_param.overlay_frame_height = req_p->overlay_frame_height;
    capture_isp_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;
    capture_isp_param.overlay_palette_size = req_p->overlay_palette_size;
    capture_isp_param.overlay_palette_addr = (kal_uint32)req_p->overlay_palette_addr;

    capture_isp_param.image_pitch_mode = KAL_FALSE;         /* req_p->image_pitch_mode; */
    capture_isp_param.image_data_format = req_p->image_data_format;
    capture_isp_param.image_bg_image_width = req_p->image_pitch_bytes;

    /* ISP Setting */
    if (get_camera_digital_zoom_step() !=0)
    {
        kal_uint32 buffer_size;
        buffer_size = MAX_CAM_CAP_DIGITAL_ZOOM_WORKING_BUF_SIZE;
        
        cam_context_p->raw_capture_enable = capture_isp_param.raw_capture_enable = KAL_TRUE;
        ASSERT(cam_context_p->raw_image_buffer_address==NULL);

        cam_context_p->raw_image_buffer_address = capture_isp_param.raw_image_buffer_address = (kal_uint32) med_alloc_ext_mem(buffer_size);
        ASSERT(capture_isp_param.raw_image_buffer_address!=NULL)
    }
    else
    {   
        capture_isp_param.raw_capture_enable = KAL_FALSE;
        capture_isp_param.raw_image_buffer_address = 0;
    }

    /* Display Setting */
    capture_isp_param.lcd_id = req_p->lcd_id;
    capture_isp_param.lcm_start_x = req_p->lcm_start_x;
    capture_isp_param.lcm_start_y = req_p->lcm_start_y;
    capture_isp_param.lcm_end_x = req_p->lcm_end_x;
    capture_isp_param.lcm_end_y = req_p->lcm_end_y;
    capture_isp_param.roi_offset_x = req_p->roi_offset_x;
    capture_isp_param.roi_offset_y = req_p->roi_offset_y;
    capture_isp_param.update_layer = req_p->update_layer;
    capture_isp_param.hw_update_layer = req_p->hw_update_layer;
    capture_isp_param.display = req_p->display;
    capture_isp_param.frame_buffer_address = req_p->frame_buffer_address;
    capture_isp_param.frame_buffer_size = req_p->frame_buffer_size;
    capture_isp_param.tv_output = req_p->tv_output;
    capture_isp_param.tv_output_width = req_p->tv_output_width;
    capture_isp_param.tv_output_height = req_p->tv_output_height;
    capture_isp_param.tv_output_offset_x = req_p->tv_output_offset_x;
    capture_isp_param.tv_output_offset_y = req_p->tv_output_offset_y;
    capture_isp_param.tv_output_buffer1_address = req_p->tv_output_buffer1_address;
    capture_isp_param.tv_output_buffer2_address = req_p->tv_output_buffer2_address;
    capture_isp_param.tv_output_buffer_size = req_p->tv_output_buffer_size;
    capture_isp_param.cam_capture_jpeg_cb = cam_capture_callback;

    /* The following code is for continuous shot control */
    if (req_p->continue_capture == KAL_FALSE) 
    {
        capture_isp_param.snapshot_number = MULTISHOT_FALSE;
    }
    else if (req_p->continue_capture == KAL_TRUE && cam_context_p->continue_capture == KAL_FALSE)
    {
        capture_isp_param.snapshot_number = MULTISHOT_FIRST;
        cam_context_p->continue_capture = req_p->continue_capture;
    }
    else
    {
        capture_isp_param.snapshot_number = MULTISHOT_NOT_FIRST;
    }
   

    cam_context_p->special_capture_mode = req_p->special_capture_mode;

    if (cam_context_p->special_capture_mode == CAM_CAPTURE_BURST_SHOT_MODE || cam_context_p->special_capture_mode == CAM_CAPTURE_BRACKET_EXPOSURE_MODE)
        cam_context_p->jpeg_file_info_p = (jpegs_struct *)req_p->jpegs_p;
    else 
        cam_context_p->jpeg_file_info_p = &cam_context_p->jpeg_file_info;


    /* default value of special capture mode parameters */
    capture_isp_param.bracket_enable = KAL_FALSE;
    capture_isp_param.expo_bracket_level = 1;
    capture_isp_param.pano_enable = KAL_FALSE;

    switch(req_p->special_capture_mode)
    {
        case CAM_CAPTURE_PANORAMA_SHOT_MODE:
        capture_isp_param.pano_enable = KAL_TRUE;
        cam_context_p->direction = req_p->direction;        
        cam_context_p->current_shot_number = req_p->current_shot_number;
        cam_context_p->jpeg_file_info_p->file_address[0] = cam_context_p->capture_buffer_p;
        
        if(cam_context_p->current_shot_number == CAM_PANO_MAX_SHOT_NUM)
            cam_context_p->continue_capture = KAL_TRUE;
        else
            cam_context_p->continue_capture = KAL_FALSE;
        break;
        case CAM_CAPTURE_BRACKET_EXPOSURE_MODE:
        capture_isp_param.bracket_enable = KAL_TRUE;
        capture_isp_param.expo_bracket_level = 0;
        capture_isp_param.snapshot_number = MULTISHOT_FIRST;
        break;
        case CAM_CAPTURE_BURST_SHOT_MODE:
        case CAM_CAPTURE_BEST_SHOT_MODE:
        capture_isp_param.snapshot_number = MULTISHOT_FIRST;
        break;
        case CAM_CAPTURE_NORMAL_MODE:
        default:
        break;
    }

    capture_isp_param.binning_mode = cam_context_p->binning_mode;
    
#elif MT6225_SERIES
    capture_isp_param.image_quality = cam_context_p->image_quality = (kal_uint8) req_p->image_quality;
    capture_isp_param.jpeg_gray_mode = 0;   /* alway color mode */
    capture_isp_param.target_buffer_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
    capture_isp_param.target_buffer_size = MAX_CAM_FILE_BUFFER_LEN;

    /* allocate memory for YUV channels */
    img_width = (req_p->image_width%16==0)? req_p->image_width : 16 - (req_p->image_width%16) + req_p->image_width;
    img_height = (req_p->image_height%16==0)? req_p->image_height : 16 - (req_p->image_height%16) + req_p->image_height;
    cam_context_p->channel_size = img_width*img_height;

    if (capture_isp_param.jpeg_gray_mode ==0)
    {
        /* color mode */
        capture_isp_param.y_size = cam_context_p->channel_size;
        capture_isp_param.u_size = cam_context_p->channel_size/4;
        capture_isp_param.v_size = cam_context_p->channel_size/4;
        
        capture_isp_param.y_address = cam_context_p->y_address =
            (kal_uint32)(cam_context_p->capture_buffer_p + MAX_JPEG_ENCODE_MARGIN_LEN);
        capture_isp_param.u_address = cam_context_p->u_address =
            (kal_uint32)(cam_context_p->y_address + capture_isp_param.y_size);
        capture_isp_param.v_address = cam_context_p->v_address =
            (kal_uint32)(cam_context_p->u_address + capture_isp_param.u_size);

        ASSERT(capture_isp_param.v_address + capture_isp_param.v_size <= 
               cam_context_p->capture_buffer_p + MAX_CAM_CAPTURE_ISP_BUF_SIZE);
    }
    else
    {
        /* gray mode */
        capture_isp_param.y_size = cam_context_p->channel_size;
        capture_isp_param.u_size = 0;
        capture_isp_param.v_size = 0;
        
        capture_isp_param.y_address = cam_context_p->y_address =
            (kal_uint32)(cam_context_p->capture_buffer_p + MAX_JPEG_ENCODE_MARGIN_LEN);

        ASSERT(capture_isp_param.y_address + capture_isp_param.y_size <= 
               cam_context_p->capture_buffer_p + MAX_CAM_CAPTURE_ISP_BUF_SIZE);
    }

    #if defined(__CAM_DZ_NEED_EXTRA_MEM__)
        if (get_isp_digital_zoom_factor() > 10)
        {
            kal_uint32 buffer_size;
            buffer_size = MAX_CAM_CAP_DIGITAL_ZOOM_WORKING_BUF_SIZE;
            cam_context_p->dz_extmem_address = capture_isp_param.extmem_start_address = (kal_uint32) med_alloc_ext_mem(buffer_size);;
            cam_context_p->dz_extmem_size = capture_isp_param.extmem_size = MAX_CAM_CAP_DIGITAL_ZOOM_WORKING_BUF_SIZE;
            ASSERT(capture_isp_param.extmem_start_address != NULL);
        }
    #endif /* defined(__CAM_DZ_NEED_EXTRA_MEM__) */

#elif MT6228_SERIES
    capture_isp_param.image_quality = cam_context_p->image_quality = (kal_uint8) req_p->image_quality;
    capture_isp_param.jpeg_gray_mode = 0;   /* alway color mode */
    capture_isp_param.target_buffer_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
    capture_isp_param.target_buffer_size = MAX_CAM_FILE_BUFFER_LEN;

    /* ISP Setting */
    capture_isp_param.flash_mode = req_p->flash_mode;

    /* JPEG Setting */
    capture_isp_param.jpeg_yuv_mode = JPEG_FORMAT_YUV420;   /* req_p->jpeg_yuv_mode; */
    capture_isp_param.thumbnail_mode = KAL_FALSE;           /* req_p->thumbnail_mode; */
    capture_isp_param.thumbnail_width = req_p->thumbnail_width;
    capture_isp_param.thumbnail_height = req_p->thumbnail_height;
    /* IPP Setting */
    capture_isp_param.overlay_frame_mode = req_p->overlay_frame_mode;
    capture_isp_param.overlay_color_depth = req_p->overlay_color_depth;
    capture_isp_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
    capture_isp_param.overlay_frame_width = req_p->overlay_frame_width;
    capture_isp_param.overlay_frame_height = req_p->overlay_frame_height;
    capture_isp_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;

    capture_isp_param.image_pitch_mode = KAL_FALSE;         /* req_p->image_pitch_mode; */
    capture_isp_param.image_data_format = req_p->image_data_format;
    capture_isp_param.image_pitch_bytes = req_p->image_pitch_bytes;
    /* Display Setting */
    capture_isp_param.lcd_id = req_p->lcd_id;
    capture_isp_param.lcm_start_x = req_p->lcm_start_x;
    capture_isp_param.lcm_start_y = req_p->lcm_start_y;
    capture_isp_param.lcm_end_x = req_p->lcm_end_x;
    capture_isp_param.lcm_end_y = req_p->lcm_end_y;
    capture_isp_param.roi_offset_x = req_p->roi_offset_x;
    capture_isp_param.roi_offset_y = req_p->roi_offset_y;
    capture_isp_param.update_layer = req_p->update_layer;
    capture_isp_param.hw_update_layer = req_p->hw_update_layer;
    capture_isp_param.display = req_p->display;
    capture_isp_param.frame_buffer_address = req_p->frame_buffer_address;
    capture_isp_param.frame_buffer_size = req_p->frame_buffer_size;
    capture_isp_param.tv_output = req_p->tv_output;
    capture_isp_param.tv_output_width = req_p->tv_output_width;
    capture_isp_param.tv_output_height = req_p->tv_output_height;
    capture_isp_param.tv_output_offset_x = req_p->tv_output_offset_x;
    capture_isp_param.tv_output_offset_y = req_p->tv_output_offset_y;
    capture_isp_param.tv_output_buffer1_address = req_p->tv_output_buffer1_address;
    capture_isp_param.tv_output_buffer2_address = req_p->tv_output_buffer2_address;
    capture_isp_param.tv_output_buffer_size = req_p->tv_output_buffer_size;
    capture_isp_param.snapshot_number = cam_context_p->snapshot_number;
    capture_isp_param.cam_capture_jpeg_cb = cam_capture_callback;
    if (cam_context_p->snapshot_number == 1)
    {
        capture_isp_param.jpeg_file_info = (isp_burst_capture_info_struct*) & cam_context_p->jpeg_file_info;
    }
    else
    {
        ASSERT(req_p->jpegs_p != NULL);
        capture_isp_param.jpeg_file_info = (isp_burst_capture_info_struct*) req_p->jpegs_p;
    }
#else /* MT6228_SERIES */
    capture_isp_param.image_quality = cam_context_p->image_quality = (kal_uint8) req_p->image_quality;
    capture_isp_param.jpeg_gray_mode = 0;   /* alway color mode */
    capture_isp_param.target_buffer_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
    capture_isp_param.target_buffer_size = MAX_CAM_FILE_BUFFER_LEN;

    #if !defined(MT6219)
        capture_isp_param.flash_mode = req_p->flash_mode;
    #endif
#endif /* MT6228_SERIES */

    MED_CAM_GET_START_TIME(CAM_CAPTURE_JPEG_DURATION);
    MED_CAM_START_LOGGING("CPJ");

#if (MT6238_SERIES)
    med_start_timer(CAM_CAPTURE_TIMEOUT_TIMER, CAM_CAPTURE_TIMEOUT_DURATION, cam_capture_timeout_callback, 0);
#endif

#ifdef __MTK_TARGET__
    file_size = camera_capture_jpeg_process(&capture_isp_param);
#endif /* __MTK_TARGET__ */

#if (!MT6228_SERIES) && (!MT6238_SERIES)
    MED_CAM_STOP_LOGGING("CPJ");
    MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_CAPTURE_JPEG_DURATION);
#endif /* (!MT6228_SERIES) && (!MT6238_SERIES) */

#if (MT6225_SERIES) && !defined(WIN32)
    cam_context_p->memory_output = req_p->memory_output;
    cam_context_p->memory_output_width = req_p->memory_output_width;
    cam_context_p->memory_output_height = req_p->memory_output_height;
    cam_context_p->memory_output_buffer_address = req_p->memory_output_buffer_address;
    cam_context_p->memory_output_buffer_size = req_p->memory_output_buffer_size;

    if (cam_context_p->memory_output == KAL_TRUE)
    {
         iul_yuv420_non_interleave_to_rgb565_general_resize((unsigned char *)cam_context_p->y_address,
                                                           (unsigned char *)cam_context_p->u_address,
                                                           (unsigned char *)cam_context_p->v_address,
                                                           capture_isp_param.target_width,
                                                           capture_isp_param.target_height,                                                       
                                                           (unsigned short*)cam_context_p->memory_output_buffer_address, 
                                                           cam_context_p->memory_output_width, 
                                                           cam_context_p->memory_output_height);
    }

    /* free internal mem for later jpeg encoding. */
    CAM_FREE_INT_BUFFER();
#endif


#if (MT6228_SERIES) || (MT6238_SERIES)
    return 1;
#else /* (MT6228_SERIES) */
    return file_size;
#endif /* (MT6228_SERIES) */

#else /* ISP_SUPPORT */
    return MED_RES_FAIL;
#endif /* ISP_SUPPORT */
}


/*****************************************************************************
 * FUNCTION
 *  cam_capture_from_layer
 * DESCRIPTION
 *  This function is to capture image from lcd layers to jpeg file.
 * PARAMETERS
 *  req_p       [?]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
kal_uint32 cam_capture_from_layer(media_cam_capture_req_struct *req_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->capture_mem_result = 0;
    /* store for later encode use */
    cam_context_p->image_width = req_p->image_width;
    cam_context_p->image_height = req_p->image_height;
    cam_context_p->image_quality = req_p->image_quality;

#if defined(__DIRECT_SENSOR_SUPPORT__)

    #if defined(DYNAMIC_CODE_MANAGER) && defined(__MTK_TARGET__)
    DCM_Load(DYNAMIC_CODE_JPEG_ENC, NULL, NULL);
    #endif

    capture_mem_param.zoom_factor = cam_context_p->zoom_factor;
    capture_mem_param.snapshot_number = cam_context_p->snapshot_number;

    /* step 1. get image from lcd layers to image buffer */
    if (cam_context_p->lcd_rotate == CAM_IMAGE_ROTATE_90 || cam_context_p->lcd_rotate == CAM_IMAGE_ROTATE_270)
    {
        capture_mem_param.capture_width = req_p->image_height;
        capture_mem_param.capture_height = req_p->image_width;
    }
    else
    {
        capture_mem_param.capture_width = req_p->image_width;
        capture_mem_param.capture_height = req_p->image_height;
    }

    capture_mem_param.intmem_start_address = med_get_med_int_dcm_mem(cam_capture_mem[0]);
    cam_context_p->intmem_start_address = NULL;
    capture_mem_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_capture_mem[0];
	
    capture_mem_param.capture_buff_addr = cam_context_p->extmem_start_address =
        (kal_uint32) cam_context_p->capture_buffer_p;

#else
    /* step 1. get image from lcd layers to image buffer */
    if (cam_context_p->lcd_rotate == CAM_IMAGE_ROTATE_90 || cam_context_p->lcd_rotate == CAM_IMAGE_ROTATE_270)
    {
        capture_mem_param.target_width = req_p->image_height;
        capture_mem_param.target_height = req_p->image_width;
    }
    else
    {
        #if MT6238_SERIES /* need to switch width and height */
        if (cam_context_p->rot_angle == IMG_ROT_ANGLE_90 || cam_context_p->rot_angle == IMG_ROT_ANGLE_270)
        {
            capture_mem_param.target_width = req_p->image_height;
            capture_mem_param.target_height = req_p->image_width;
        }
        else
        #endif
        {
            capture_mem_param.target_width = req_p->image_width;
            capture_mem_param.target_height = req_p->image_height;
        }
    }
    capture_mem_param.intmem_start_address = cam_context_p->intmem_start_address =
        (kal_uint32) med_alloc_int_mem(cam_capture_mem[0]);
    capture_mem_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_capture_mem[0];
    capture_mem_param.extmem_start_address = 0;
    capture_mem_param.extmem_size = 0;
    capture_mem_param.imgdma_buffer_size = cam_context_p->frame_buffer_size;
    capture_mem_param.imgdma_buffer_address = (kal_uint32) cam_context_p->frame_buffer_p;
    capture_mem_param.block_mode = 0;
    /* for lcd if */
    capture_mem_param.dest_buffer_size = req_p->image_width * req_p->image_height * 2;
#if MT6225_SERIES
    capture_mem_param.dest_buffer_address = cam_context_p->extmem_start_address =
        (kal_uint32) cam_context_p->capture_buffer_p;
#else /* MT6228_SERIES or MT6238_SERIES*/
    capture_mem_param.dest_buffer_address = cam_context_p->extmem_start_address =
        (kal_uint32) med_alloc_ext_mem(capture_mem_param.dest_buffer_size);
#endif
    capture_mem_param.roi_offset_x = req_p->roi_offset_x;
    capture_mem_param.roi_offset_y = req_p->roi_offset_y;
    capture_mem_param.roi_width = req_p->image_width;
    capture_mem_param.roi_height = req_p->image_height;
    capture_mem_param.update_layer = req_p->capture_layer;
    capture_mem_param.hw_update_layer = cam_context_p->hw_update_layer;

#if MT6238_SERIES
    /* trigger_lcd must be KAL_TRUE when capture layer to memory or file */
    capture_mem_param.trigger_lcd = KAL_TRUE;
    capture_mem_param.yuv_output_enable_mode = KAL_FALSE;
    /* IPP Setting */
    capture_mem_param.overlay_frame_mode = req_p->overlay_frame_mode;
    capture_mem_param.overlay_color_depth = req_p->overlay_color_depth;
    capture_mem_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
    capture_mem_param.overlay_frame_width = req_p->overlay_frame_width;
    capture_mem_param.overlay_frame_height = req_p->overlay_frame_height;
    capture_mem_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;
    capture_mem_param.image_pitch_mode = KAL_FALSE; /* req_p->image_pitch_mode; */
    capture_mem_param.image_data_format = req_p->image_data_format;
    capture_mem_param.image_bg_image_width = req_p->image_bg_image_width;
    /* Display Setting */
    capture_mem_param.roi_offset_x = req_p->roi_offset_x;
    capture_mem_param.roi_offset_y = req_p->roi_offset_y;

    capture_mem_param.image_clip_mode = KAL_FALSE;
    capture_mem_param.image_clip_left = 0;
    capture_mem_param.image_clip_right = 0;
    capture_mem_param.image_clip_top = 0;
    capture_mem_param.image_clip_bottom= 0;
    /* LCD Setting */
    capture_mem_param.memory_data_format = 0;
    capture_mem_param.lcd_id = req_p->lcd_id;
    capture_mem_param.rot_angle = cam_context_p->rot_angle;
#elif MT6228_SERIES
    capture_mem_param.manual_wb = req_p->manual_wb;
    /* IPP Setting */
    capture_mem_param.overlay_frame_mode = req_p->overlay_frame_mode;
    capture_mem_param.overlay_color_depth = req_p->overlay_color_depth;
    capture_mem_param.overlay_frame_source_key = req_p->overlay_frame_source_key;
    capture_mem_param.overlay_frame_width = req_p->overlay_frame_width;
    capture_mem_param.overlay_frame_height = req_p->overlay_frame_height;
    capture_mem_param.overlay_frame_buffer_address = req_p->overlay_frame_buffer_address;
    capture_mem_param.image_pitch_mode = KAL_FALSE; /* req_p->image_pitch_mode; */
    capture_mem_param.image_data_format = req_p->image_data_format;
    capture_mem_param.image_pitch_bytes = req_p->image_pitch_bytes;
    /* Display Setting */
    capture_mem_param.roi_offset_x = req_p->roi_offset_x;
    capture_mem_param.roi_offset_y = req_p->roi_offset_y;

    capture_mem_param.image_clip_mode = KAL_FALSE;
    capture_mem_param.image_clip_x1 = 0;
    capture_mem_param.image_clip_x2 = 0;
    capture_mem_param.image_clip_y1 = 0;
    capture_mem_param.image_clip_y2 = 0;
    /* LCD Setting */
    capture_mem_param.memory_data_format = 0;

#endif /* MT6228_SERIES */
    /* capture */
#endif /* __DIRECT_SENSOR_SUPPORT */

#if defined(__CAM_DZ_NEED_EXTRA_MEM__)
    if (get_isp_digital_zoom_factor() > 10)
    {
        kal_uint32 buffer_size;
        buffer_size = MAX_CAM_CAP_DIGITAL_ZOOM_WORKING_BUF_SIZE;
        cam_context_p->dz_extmem_address = capture_mem_param.extmem_start_address = (kal_uint32) med_alloc_ext_mem(buffer_size);;
        cam_context_p->dz_extmem_size = capture_mem_param.extmem_size = MAX_CAM_CAP_DIGITAL_ZOOM_WORKING_BUF_SIZE;
        ASSERT(capture_mem_param.extmem_start_address != NULL);
    }
#endif /* defined(__CAM_DZ_NEED_EXTRA_MEM__) */

#ifdef __MTK_TARGET__

    MED_CAM_GET_START_TIME(CAM_CAPTURE_JPEG_DURATION);
    MED_CAM_START_LOGGING("CPM");
    cam_context_p->capture_mem_result = camera_capture_mem_process(&capture_mem_param);
    MED_CAM_STOP_LOGGING("CPM");
    MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_CAPTURE_MEM_DURATION);

#endif
    /* free internal mem for capture */
    CAM_FREE_INT_BUFFER();

#if defined(__DIRECT_SENSOR_SUPPORT__)
    med_free_med_int_dcm_mem();
    #if defined(DYNAMIC_CODE_MANAGER) && defined(__MTK_TARGET__)
    DCM_Unload(DYNAMIC_CODE_JPEG_ENC);
    #endif
#endif


#if defined(__DIRECT_SENSOR_SUPPORT__)
    cam_context_p->memory_output = req_p->memory_output;
    cam_context_p->memory_output_width = req_p->memory_output_width;
    cam_context_p->memory_output_height = req_p->memory_output_height;
    cam_context_p->memory_output_buffer_address = req_p->memory_output_buffer_address;
    cam_context_p->memory_output_buffer_size = req_p->memory_output_buffer_size;

    if (cam_context_p->memory_output == KAL_TRUE)
    {
        MED_CAM_GET_START_TIME(CAM_YUV2RGB_RESIZE_DURATION);
        MED_CAM_START_LOGGING("CRE");
        if (req_p->image_width==req_p->memory_output_width && req_p->image_height==req_p->memory_output_height)
        {
            iul_yuv422_interleave_to_rgb565((unsigned int*)cam_context_p->extmem_start_address,(unsigned short*)cam_context_p->memory_output_buffer_address, req_p->image_width, req_p->image_height);
        }
        else if ((req_p->image_width/2)==req_p->memory_output_width && (req_p->image_height/2)==req_p->memory_output_height)
        {
            iul_yuv422_interleave_to_rgb565_quarter_size((unsigned int*)cam_context_p->extmem_start_address,(unsigned short*)cam_context_p->memory_output_buffer_address, req_p->image_width, req_p->image_height);
        }
        else
        {
            iul_yuv422_interleave_to_rgb565_general_resize((unsigned int*)cam_context_p->extmem_start_address,req_p->image_width, req_p->image_height, 
                                                               (unsigned short*)cam_context_p->memory_output_buffer_address, cam_context_p->memory_output_width, cam_context_p->memory_output_height);
        }
        MED_CAM_STOP_LOGGING("CRE");
        MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_YUV2RGB_RESIZE_DURATION);
    }
#endif



    /* if manual_wb equals TRUE, call camera_mwb_process then return */
#if (MT6228_SERIES)
    if (capture_mem_param.manual_wb)
    {
        camera_mwb_process_struct mwb_para;

        mwb_para.mwb_buffer_address = capture_mem_param.dest_buffer_address;
        mwb_para.mwb_image_height = capture_mem_param.target_width;
        mwb_para.mwb_image_width = capture_mem_param.target_height;
        camera_mwb_process(&mwb_para);
        return 0;
    }
#endif /* (MT6228_SERIES) */
    /* step 2. encode image buffer to file */
#if MT6238_SERIES
{
    JPEG_STATUS_ENUM _jpeg_status = 0;
    JPEG_ENCODER_HANDLE _jpeg_encoder_hdl = NULL;
    kal_uint8 *_jpeg_enc_output_file_addr;
    kal_uint32 _jpeg_enc_output_file_size = 0;

    kal_uint32 _intMemSize = 0xFFFFFFFF;
    kal_uint32 _extMemSize = 0xFFFFFFFF;
    void *_extMem = NULL;
    void *_intMem = NULL;

    _jpeg_status = jpegEncGetEncoder(JPEG_CODEC_TYPE_HW, &_jpeg_encoder_hdl);

    _jpeg_status = jpegEncSetSrcMode(_jpeg_encoder_hdl, JPEG_ENCODE_SOURCE_RGB_BUFFER);

    _jpeg_status = jpegEncSetSrcRGBFormat(_jpeg_encoder_hdl, JPEG_RGB_FORMAT_RGB565);

    _jpeg_status = jpegEncSetSrcDimension(_jpeg_encoder_hdl, req_p->image_width, req_p->image_height);


    /*
     * for fixing MAUI_01427881, currently our lcd roi range is 0~1023, in HVGA project, Java need to capture roi range > 1023
     * workaround: if capturing layer == hw_udpate (preview) layer only, we will encode imgdma_buffer instead of dest_buffer 
     */
    if (cam_context_p->hw_update_layer == req_p->capture_layer)
    {
        _jpeg_status = jpegEncSetRGBBuffer(_jpeg_encoder_hdl, (void *)capture_mem_param.imgdma_buffer_address);
    }
    else
    {
        _jpeg_status = jpegEncSetRGBBuffer(_jpeg_encoder_hdl, (void *)capture_mem_param.dest_buffer_address);
    }
    
    _jpeg_status = jpegEncQueryWorkingMemory(_jpeg_encoder_hdl, &_intMemSize, &_extMemSize);

    /// destination
    _jpeg_status = jpegEncSetDstBuffer(_jpeg_encoder_hdl, (void*)cam_context_p->capture_buffer_p, MAX_CAM_ENC_IMG_FILE_BUF_LEN * cam_context_p->snapshot_number);

    _jpeg_status = jpegEncSetDstDimension(_jpeg_encoder_hdl, req_p->image_width, req_p->image_height);

#if defined(EXIF_SUPPORT)
    _jpeg_status = jpegEncSetDstFileFormat(_jpeg_encoder_hdl, JPEG_FILE_FORMAT_EXIF);
#else
    _jpeg_status = jpegEncSetDstFileFormat(_jpeg_encoder_hdl, JPEG_FILE_FORMAT_JPEG);
#endif
    _jpeg_status = jpegEncSetDstThumbnail(_jpeg_encoder_hdl, JPEG_THUMBNAIL_TYPE_NONE, 
                                                           0, 
                                                           0);

    _jpeg_status = jpegEncSetDstQuality(_jpeg_encoder_hdl, cam_context_p->image_quality);

    _jpeg_status = jpegEncSetDstSampleFormat(_jpeg_encoder_hdl, JPEG_SAMPLING_FORMAT_YUV422);

    if (_intMemSize)
    {
     _intMem = (void *)med_alloc_int_mem(_intMemSize);
     ASSERT(_intMem);
    }

    if (_extMemSize)
    {
     _extMem = (void *)med_alloc_ext_mem(_extMemSize);
     ASSERT(_extMem);
    }

    jpegEncSetWorkingMemory(_jpeg_encoder_hdl, _intMem, _intMemSize, _extMem, _extMemSize);

    _jpeg_status = jpegEncSetCallbackFunction(_jpeg_encoder_hdl, cam_jpeg_encoder_callback);

    _jpeg_state = JPEG_CODEC_STATE_BUSY;

    _jpeg_status = jpegEncStart(_jpeg_encoder_hdl);


    /// the following is to simulate the behavior of message handler
    while (JPEG_CODEC_STATE_COMPLETE != _jpeg_state) {
     switch (_jpeg_state) {
     
     case JPEG_CODEC_STATE_BUSY:
        /// still decoding, nothing to do...
        kal_sleep_task(1);
        break;

     case JPEG_CODEC_STATE_PAUSED:
        ASSERT(0);
        break;

     case JPEG_CODEC_STATE_ERROR:
        ASSERT(0);
        break;
        
     default:
        ASSERT(0);
        break;
     }
    }

    _jpeg_status = jpegEncGetEncodedData(_jpeg_encoder_hdl, &_jpeg_enc_output_file_addr, &_jpeg_enc_output_file_size);


    /// clean up
    jpegEncReleaseEncoder(_jpeg_encoder_hdl);

    if (_extMem)
    {
     med_free_ext_mem(&_extMem);
    }

    if (_intMem)
    {
     med_free_int_mem(&_intMem);
    }

    return _jpeg_enc_output_file_size;
}
#else
    return 0;
#endif
}


/*****************************************************************************
 * FUNCTION
 *  cam_release_af_lens_if_not_continuous_shot
 * DESCRIPTION
 *  This function is to release autofocus lens
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
static void cam_release_af_lens_if_not_continuous_shot(void)
{
#if defined(AF_SUPPORT)
    if (cam_context_p->continue_capture == KAL_FALSE && cam_context_p->af_mode != CAM_AF_MANUAL_MODE)
    {
        camera_operation_setting((kal_uint8) CAM_AF_KEY, (kal_uint16) CAM_AF_RELEASE);
    }
#endif /* defined(AF_SUPPORT) */
}


/*****************************************************************************
 * FUNCTION
 *  cam_encode_layer
 * DESCRIPTION
 *  ask MED_CAM to encode cam_context_p->extmem_start_address as jpeg buffer
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
kal_uint32 cam_encode_layer(void)
{

#if !MT6238_SERIES
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

#if MT6225_SERIES
    kal_uint32 img_width ,img_height;
#endif
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if MT6225_SERIES
    if (cam_context_p->source_device == CAM_SRC_MEM)
    {
    #if defined(__DIRECT_SENSOR_SUPPORT__)
        jpg_encode.image_buffer_address = capture_mem_param.capture_buff_addr;
        jpg_encode.input_type = IMAGE_FORMAT_YUV422;
    #elif defined(ISP_SUPPORT)
        jpg_encode.image_buffer_address = capture_mem_param.dest_buffer_address;
        jpg_encode.input_type = IMAGE_FORMAT_RGB565;
    #endif
        jpg_encode.output_type = IMAGE_FORMAT_YUV420;

        img_width = (cam_context_p->image_width%16==0)? cam_context_p->image_width : 16 - (cam_context_p->image_width%16) + cam_context_p->image_width;
        img_height = (cam_context_p->image_height%16==0)? cam_context_p->image_height : 16 - (cam_context_p->image_height%16) + cam_context_p->image_height;
        cam_context_p->channel_size = img_width*img_height;

        /* color mode */
        cam_context_p->y_address = (kal_uint32) (jpg_encode.image_buffer_address + MAX_CAM_CAP_LCD_EXT_MEM_SIZE);
        cam_context_p->u_address = (kal_uint32) (cam_context_p->y_address + cam_context_p->channel_size);
        cam_context_p->v_address = (kal_uint32) (cam_context_p->u_address + cam_context_p->channel_size/4);

        ASSERT(cam_context_p->v_address + cam_context_p->channel_size/4 <= 
               jpg_encode.image_buffer_address + MAX_CAM_CAPTURE_MEM_BUF_SIZE);
        
    #if defined(__SW_JPEG_CODEC_SUPPORT__)
        jpg_encode.output_file_handle = NULL;
    #endif
        jpg_encode.jpeg_file_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
    }
    else if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        jpg_encode.image_buffer_address = NULL;
        jpg_encode.input_type = IMAGE_FORMAT_YUV420;
        jpg_encode.output_type = IMAGE_FORMAT_YUV420;
    #ifdef __SW_JPEG_CODEC_SUPPORT__
        #ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__
        jpg_encode.output_file_handle = &cam_context_p->fsal_file;
        jpg_encode.jpeg_file_start_address = NULL;
        #else
        jpg_encode.output_file_handle = NULL;
        jpg_encode.jpeg_file_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
        #endif
    #endif
    }

    jpg_encode.jpeg_yuv_data[0] = (kal_uint8*) cam_context_p->y_address;
    jpg_encode.jpeg_yuv_data[1] = (kal_uint8*) cam_context_p->u_address;
    jpg_encode.jpeg_yuv_data[2] = (kal_uint8*) cam_context_p->v_address;

    jpg_encode.jpeg_yuv_size[0] = cam_context_p->channel_size;
    jpg_encode.jpeg_yuv_size[1] = cam_context_p->channel_size/4;
    jpg_encode.jpeg_yuv_size[2] = cam_context_p->channel_size/4;
    
    #ifdef EXIF_SUPPORT
    cam_context_p->exif_thumbnail_address = (kal_uint32) med_alloc_ext_mem(MAX_CAM_ENC_EXIF_THUMBNAIL_BUF_SIZE);
    cam_context_p->exif_work_address = (kal_uint32)med_alloc_ext_mem(MAX_CAM_ENC_EXIF_WORK_BUF_SIZE);
    
    jpg_encode.thumbnail_yuv_data[0] = (kal_uint8*)cam_context_p->exif_thumbnail_address;
    jpg_encode.thumbnail_yuv_data[1] = (kal_uint8*)(cam_context_p->exif_thumbnail_address + MAX_CAM_ENC_EXIF_THUMBNAIL_BUF_SIZE*2/3);
    jpg_encode.thumbnail_yuv_data[2] = (kal_uint8*)(jpg_encode.thumbnail_yuv_data[1] + MAX_CAM_ENC_EXIF_THUMBNAIL_BUF_SIZE/6);
    jpg_encode.app_buffer_addr = cam_context_p->exif_work_address;    
    jpg_encode.jpeg_app_type = JPEG_APP_EXIF;
    #else
    jpg_encode.thumbnail_yuv_data[0] = 0;
    jpg_encode.thumbnail_yuv_data[1] = 0;
    jpg_encode.thumbnail_yuv_data[2] = 0;
    jpg_encode.app_buffer_addr = 0;
    jpg_encode.jpeg_app_type = JPEG_APP_NONE;
    #endif
#else
    jpg_encode.type = IBR1_TYPE_RGB565;
    jpg_encode.data_order = IBR1_ORDER_RGB888;
    jpg_encode.extmem_size = img_context_p->extmem_size = MAX_IMG_ENC_EXT_MEM_SIZE;
    if (MAX_IMG_ENC_EXT_MEM_SIZE > 0)
    {
        jpg_encode.extmem_start_address = img_context_p->extmem_start_address =
            (kal_uint32) med_alloc_ext_mem(MAX_IMG_ENC_EXT_MEM_SIZE);
    }
    else
    {
        jpg_encode.extmem_start_address = img_context_p->extmem_start_address = 0;
    }
    jpg_encode.target_width = cam_context_p->image_width;
    jpg_encode.target_height = cam_context_p->image_height;
    jpg_encode.jpeg_gray_mode = 0;
    jpg_encode.jpeg_encode_cb = cam_img_encode_callback;
    jpg_encode.image_buffer_address = (kal_uint32) cam_context_p->extmem_start_address;
    jpg_encode.jpeg_file_start_address = (kal_uint32) cam_context_p->capture_buffer_p;
#endif
    jpg_encode.intmem_size = img_context_p->intmem_size = MAX_IMG_ENC_INT_MEM_SIZE;
    if (MAX_IMG_ENC_INT_MEM_SIZE > 0)
    {
        img_context_p->intmem_src = IMG_INTMEM_SRC_INTERNAL;
        jpg_encode.intmem_start_address = img_context_p->intmem_start_address =
            (kal_uint32) med_alloc_int_mem(MAX_IMG_ENC_INT_MEM_SIZE);
    }
    else
    {
        jpg_encode.intmem_start_address = img_context_p->intmem_start_address = 0;
    }

    jpg_encode.image_width = cam_context_p->image_width;
    jpg_encode.image_height = cam_context_p->image_height;
    jpg_encode.image_quality = cam_context_p->image_quality;

    if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        /* currently, only MT6225/6235 will capture from isp and be here to encode layer */
        jpg_encode.jpeg_file_buffer_size = MAX_CAM_FILE_BUFFER_LEN;
    }
    else if (cam_context_p->source_device == CAM_SRC_MEM)
    {
        jpg_encode.jpeg_file_buffer_size = MAX_CAM_ENC_IMG_FILE_BUF_LEN * cam_context_p->snapshot_number;
    }

#if MT6228_SERIES
    /* JPEG Setting */
    jpg_encode.jpeg_yuv_mode = JPEG_FORMAT_YUV420;  /* req_p->jpeg_yuv_mode; */
    jpg_encode.thumbnail_mode = KAL_FALSE;          /* req_p->thumbnail_mode; */
    jpg_encode.thumbnail_width = 0;
    jpg_encode.thumbnail_height = 0;
    /* IPP Setting */
    jpg_encode.overlay_frame_mode = KAL_FALSE;      /* req_p->overlay_frame_mode; */
#endif /* MT6228_SERIES */

#ifdef __MTK_TARGET__
#if defined(DYNAMIC_CODE_MANAGER) && defined(__MTK_TARGET__) && defined(__DIRECT_SENSOR_SUPPORT__)
    DCM_Load(DYNAMIC_CODE_JPEG_ENC,NULL,NULL);
#endif

    MED_CAM_GET_START_TIME(CAM_ENCODE_LAYER_DURATION);

    MED_CAM_START_LOGGING("CEN");
    img_context_p->file_size = jpeg_encode_process(&jpg_encode);
    MED_CAM_STOP_LOGGING("CEN");

    MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_ENCODE_LAYER_DURATION);

#if defined(DYNAMIC_CODE_MANAGER) && defined(__MTK_TARGET__) && defined(__DIRECT_SENSOR_SUPPORT__) 
    DCM_Unload(DYNAMIC_CODE_JPEG_ENC);
#endif
    exit_jpeg_encode_process();
#endif /* __MTK_TARGET__ */

    /* free internal mem for capture */
    CAM_FREE_INT_BUFFER();

    return img_context_p->file_size;
#else /* !MT6238_SERIES*/
    return 0;
#endif

}



void cam_save_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 result = MED_RES_OK;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* state must be in CAM_CAPTURE */
    ASSERT(CAM_IN_STATE(CAM_CAPTURE));

    #if (MT6238_SERIES)
        if (cam_context_p->source_device == CAM_SRC_ISP)
        {
            if ((cam_context_p->snapshot_number == 1) || (cam_context_p->special_capture_mode == CAM_CAPTURE_BEST_SHOT_MODE))
            {
                result = cam_close_image_file(cam_context_p->jpeg_file_info_p->file_size[0]);
                cam_set_result(result);
                CAM_ENTER_STATE(CAM_READY);
                CAM_SET_EVENT(CAM_EVT_SAVE);
            }
            else
            ASSERT(0);
        }
        else if (cam_context_p->source_device == CAM_SRC_MEM)
        {
            result = cam_close_image_file(cam_context_p->file_size);
            CAM_FREE_CAPTURE_BUFFER();
            cam_set_result(result);
            CAM_ENTER_STATE(CAM_READY);
            CAM_SET_EVENT(CAM_EVT_SAVE);            
        }
    #elif (MT6228_SERIES)
        /* if source_device = MEM, must finish capture process */
        /* if source_device = ISP, we wait for callback function to finish capture process */
        if (cam_context_p->source_device == CAM_SRC_MEM)
        {       
            if (cam_context_p->snapshot_number == 1)
            {
                cam_context_p->file_size = cam_encode_layer();
                cam_release_memory();
                img_release_memory();
                jfif_thumbnail_swap((kal_uint32) cam_context_p->capture_buffer_p);
                result = cam_close_image_file(cam_context_p->file_size);
                cam_set_result(result);
                CAM_ENTER_STATE(CAM_READY);

                if (cam_context_p->media_mode == MED_MODE_BUFFER)
                {
                    *(cam_context_p->file_size_p) = cam_context_p->file_size;
                }

                CAM_SET_EVENT(CAM_EVT_SAVE);
            }
            else 
            ASSERT(0);            
        }
        else if (cam_context_p->source_device == CAM_SRC_ISP)
        {
            if (cam_context_p->snapshot_number == 1)
            {
                result = cam_close_image_file(cam_context_p->jpeg_file_info.file_size[0]);
                cam_set_result(result);
                CAM_ENTER_STATE(CAM_READY);
                CAM_SET_EVENT(CAM_EVT_SAVE);
            }
            else
            ASSERT(0);
        }        
    #else /* MT6228_SERIES */
        if (cam_context_p->source_device == CAM_SRC_MEM)
        {
            cam_context_p->file_size = cam_encode_layer();
            result = cam_close_image_file(cam_context_p->file_size);
            if (cam_context_p->media_mode == MED_MODE_BUFFER)
            {
                *(cam_context_p->file_size_p) = cam_context_p->file_size;
            }
        #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
        #endif
            cam_release_memory();
            img_release_memory();
            cam_set_result(result);
            CAM_ENTER_STATE(CAM_READY);
            CAM_SET_EVENT(CAM_EVT_SAVE);
        }
        else if (cam_context_p->source_device == CAM_SRC_ISP)
        {
            #if MT6225_SERIES
                cam_context_p->file_size = cam_encode_layer();
                img_release_memory();
            #endif

        #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
        #endif
            if (cam_context_p->snapshot_number == 1)
            {
                result = cam_close_image_file(cam_context_p->file_size);
            #if MT6225_SERIES
                if (cam_context_p->media_mode == MED_MODE_BUFFER &&
                    cam_context_p->file_size_p != NULL)
                {
                #ifdef __YUVCAM_ENCODE_DIRECT_WRITE_FILE__
                    *(cam_context_p->file_size_p) = 0;
                #else
                    *(cam_context_p->file_size_p) = cam_context_p->file_size;
                #endif
                }
            #endif /* MT6225_SERIES */ 
                cam_release_memory();
                cam_set_result(result);
                CAM_ENTER_STATE(CAM_READY);
                CAM_SET_EVENT(CAM_EVT_SAVE);
            }
            else
            ASSERT(0);
        }        

    #endif /* MT6228_SERIES */  
}


/*****************************************************************************
 * FUNCTION
 *  cam_capture_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera capture request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_capture_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_capture_req_struct *req_p;
    kal_int32 result = MED_RES_OK;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_capture_req_struct*) ilm_ptr->local_para_ptr;

    #if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
    if (cam_context_p->xenon_flash_status != CAM_XENON_FLASH_OFF)
        med_stop_timer(CAM_XENON_FLASH_CHECK_TIMER);
    #endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */

    /* it is for MoDis, we return from here */
    #if !defined(__MTK_TARGET__)
    {
        cam_set_result(MED_RES_BUSY);
        CAM_SET_EVENT(CAM_EVT_CAPTURE);
        return;
    }
    #endif

    if (CAM_IN_STATE(CAM_READY) || CAM_IN_STATE(CAM_PREVIEW))
    {
        CAM_FREE_CAPTURE_BUFFER();

        /* stop prevew before capture */
    #ifdef __MTK_TARGET__
        #if (MT6238_SERIES) || (MT6225_SERIES) 
        /* due to MT6238/MT6225 continuous shop support capture without in preview state */
            if(CAM_IN_STATE(CAM_PREVIEW))
            {
                exit_camera_preview_process();
            }
        #else
            exit_camera_preview_process();
        #endif
    #endif /* __MTK_TARGET__ */

        /* copy preview data to MMI buffer */
        if (cam_context_p->int_frame_buffer_p)
        {
            memcpy(
                (kal_uint8*) cam_context_p->frame_buffer_p,
                (kal_uint8*) cam_context_p->int_frame_buffer_p,
                cam_context_p->frame_buffer_size);
        }

        /* release preview related memory */
        cam_release_memory();

        /* free media cache memory for capture scanerio, it is temp solution for MAUI_01219822 */
        med_ext_release_temporyary(MAX_MED_CAM_CAP_EXT_MEM_SIZE);

        ASSERT(req_p->source_device == CAM_SRC_ISP || req_p->source_device == CAM_SRC_MEM);
        if ((req_p->source_device != CAM_SRC_ISP && req_p->source_device != CAM_SRC_MEM))
        {
            cam_set_result(MED_RES_ERROR);
            CAM_ENTER_STATE(CAM_READY);
            CAM_SET_EVENT(CAM_EVT_CAPTURE);
            return;
        }

        cam_context_p->media_mode = req_p->media_mode;
        cam_context_p->source_device = req_p->source_device;
        cam_context_p->snapshot_number = req_p->snapshot_number;

    #if !MT6238_SERIES
        cam_context_p->continue_capture = req_p->continue_capture;
    #endif
        cam_context_p->captured_number = 0;

        if (req_p->media_mode == MED_MODE_FILE)
        {
            kal_uint32 file_buffer_size = 0;

            /* not support snapshot number > 1 && media_mode == MED_MODE_FILE */
        #if !MT6238_SERIES
            ASSERT(req_p->media_mode == MED_MODE_FILE && cam_context_p->snapshot_number == 1);
        #endif
            if (req_p->source_device == CAM_SRC_ISP)
            {
                file_buffer_size = MAX_CAM_CAPTURE_ISP_BUF_SIZE;
            }
            else if (req_p->source_device == CAM_SRC_MEM)
            {
                file_buffer_size = MAX_CAM_CAPTURE_MEM_BUF_SIZE;
            }

            if ((result = cam_open_image_file((kal_wchar*) req_p->data, file_buffer_size)) == MED_RES_OK)
            {
                if (req_p->source_device == CAM_SRC_ISP)
                {
                    cam_context_p->file_size = cam_capture_from_isp(req_p);

                    /* enter CAPTURE state */
                    CAM_ENTER_STATE(CAM_CAPTURE);

                    /* if not 6228/6238 series: capture form isp is done after calling cam_capture_from_isp */
                #if MT6238_SERIES
                    if (req_p->capture_buffer_p!=NULL)
                    {
                        /* assign capture_buffer_p to MMI and assign file_size_p to MED Context for later use */
                        *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                        /* for BestShot use, we need to update capture_buffer_p after capture done */
                        cam_context_p->capture_buffer_pp = req_p->capture_buffer_p;
                    }

                    if (req_p->file_size_p != NULL)
                    {
                        /* assign capture_buffer_p to MMI and assign file_size_p to MED Context for later use */
                       cam_context_p->file_size_p = req_p->file_size_p;
                    }
                    else 
                    {
                        cam_context_p->file_size_p = NULL;
                    }
                #elif MT6225_SERIES
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    cam_set_result(MED_RES_OK);
                    cam_release_af_lens_if_not_continuous_shot();
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                #elif !(MT6228_SERIES || MT6238_SERIES)
                    cam_set_result(MED_RES_OK);
                    cam_release_memory();
                    cam_release_af_lens_if_not_continuous_shot();
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                #endif /* MT6228_SERIES || MT6238_SERIES */
                }
                else if (req_p->source_device == CAM_SRC_MEM)
                {
                    cam_context_p->file_size = cam_capture_from_layer(req_p);

                #if (MT6238_SERIES)
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    if (req_p->source_device == CAM_SRC_MEM)
                    {
                        cam_release_memory();
                        img_release_memory();
                        result = cam_close_image_file(cam_context_p->file_size);
                        cam_set_result(result);
                        CAM_ENTER_STATE(CAM_READY);
                        CAM_SET_EVENT(CAM_EVT_CAPTURE);
                    }
                #else /* MT6238_SERIES */
                    if (cam_context_p->capture_mem_result == LCD_OK)
                    {
                        CAM_ENTER_STATE(CAM_CAPTURE);
                        cam_set_result(MED_RES_OK);
                    }
                    else
                    {
                        CAM_ENTER_STATE(CAM_READY);
                        cam_release_memory();
                        img_release_memory();
                        cam_close_image_file(0);
                        cam_set_result(MED_RES_ERROR);
                    }
                    cam_release_af_lens_if_not_continuous_shot();
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                #endif
                }
            }
            else
            {
                /* open image file fail */
                CAM_ENTER_STATE(CAM_READY);
                cam_set_result(result);
                cam_release_af_lens_if_not_continuous_shot();
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
        }
        else if (req_p->media_mode == MED_MODE_ARRAY)
        {
        #if MT6238_SERIES
            kal_uint32 file_size = 0;
        
            if (req_p->data != NULL && req_p->file_buffer_len > 0)
            {
                cam_context_p->capture_buffer_p = (kal_uint32) req_p->data;
                cam_context_p->capture_buffer_size = req_p->file_buffer_len;

                cam_context_p->capture_buffer_pp = req_p->capture_buffer_p;
                cam_context_p->file_size_p = req_p->file_size_p;
                
                if (req_p->special_capture_mode == CAM_CAPTURE_BEST_SHOT_MODE)
                {
                    cam_context_p->capture_buffer_size = cam_context_p->capture_buffer_size >> 1;
                }
                
                if (req_p->source_device == CAM_SRC_ISP)
                {
                    file_size = cam_capture_from_isp(req_p);
                    
                    if (req_p->special_capture_mode != CAM_CAPTURE_BEST_SHOT_MODE)
                    {
                        cam_context_p->capture_buffer_p = 0;
                    }
                    CAM_ENTER_STATE(CAM_CAPTURE);

                    /* if (multiple shot && burstshot), we use non-blocking mode */
                    if (cam_context_p->snapshot_number > 1 && cam_context_p->special_capture_mode == CAM_CAPTURE_BURST_SHOT_MODE)
                    {
                        CAM_SET_EVENT(CAM_EVT_CAPTURE);
                    }
                }
                else if (req_p->source_device == CAM_SRC_MEM)
                {
                    /* NOT REACH HERE! */
                    ASSERT(0);
                }
            }
            else
            {
                cam_set_result(MED_RES_PARAM_ERROR);
                CAM_ENTER_STATE(CAM_READY);
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
        #else
            /* should no body use this mode, please copy back from w08.01 Vincent only share load*/
            ASSERT(0);
        #endif
        }
        else if (req_p->media_mode == MED_MODE_BUFFER)
        {
            kal_uint32 file_buffer_size;
        #if MT6238_SERIES
            if (req_p->source_device == CAM_SRC_ISP)
            {
                file_buffer_size = MAX_CAM_CAPTURE_ISP_BUF_SIZE;
            }
            else
            {
                file_buffer_size = MAX_CAM_CAPTURE_MEM_BUF_SIZE;
            }

            result = cam_open_image_file((kal_wchar*) req_p->data, file_buffer_size);
            if (result == MED_RES_OK)
            {
                if (req_p->source_device == CAM_SRC_ISP)
                {
                    cam_capture_from_isp(req_p);
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    /* if multiple shot, use non-blocking mode */
                    if (cam_context_p->snapshot_number > 1)
                    {
                        CAM_SET_EVENT(CAM_EVT_CAPTURE);
                    }
                    else
                    {
                        /* assign capture_buffer_p to MMI and assign file_size_p to MED Context for later use */
                        *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                        cam_context_p->file_size_p = req_p->file_size_p;
                    }
                }
                else if (req_p->source_device == CAM_SRC_MEM)
                {
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    cam_context_p->file_size = cam_capture_from_layer(req_p);
                    cam_release_memory();
                    img_release_memory();

                    *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                    *req_p->file_size_p = cam_context_p->file_size;
                    cam_set_result(MED_RES_OK);
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                }
                else
                {
                    cam_set_result(MED_RES_ERROR);
                    CAM_ENTER_STATE(CAM_READY);
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                }
            }
            else
            {
                /* open image file fail */
                CAM_ENTER_STATE(CAM_READY);
                cam_set_result(result);
                cam_release_af_lens_if_not_continuous_shot();
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
        #else /* MT6238_SERIES */
            if (req_p->source_device == CAM_SRC_ISP)
            {
                file_buffer_size = MAX_CAM_CAPTURE_ISP_BUF_SIZE;
            }
            else
            {
                file_buffer_size = MAX_CAM_CAPTURE_MEM_BUF_SIZE;
            }

            /* solution for burst shot */
            if (cam_context_p->snapshot_number > 1)
            {
                /* to release the memory allocated in MED_MODE_BUFFER mode */
                CAM_FREE_CAPTURE_BUFFER();
                cam_context_p->capture_buffer_p = (kal_uint32) med_alloc_ext_mem(file_buffer_size);
                ASSERT (cam_context_p->capture_buffer_p != NULL);
                result = MED_RES_OK;
            }
            #if (MT6228_SERIES)
            else if (!(req_p->manual_wb))
            {
                result = cam_open_image_file((kal_wchar*) req_p->data, file_buffer_size);
            }
            #else
            else 
            {
                result = cam_open_image_file((kal_wchar*) req_p->data, file_buffer_size);
                cam_context_p->file_size_p = req_p->file_size_p;
            }
            #endif
            
            if (result == MED_RES_OK)
            {
                if (req_p->source_device == CAM_SRC_ISP)
                {
                    cam_context_p->file_size = cam_capture_from_isp(req_p);

                #if (MT6228_SERIES)
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    /* if multiple shot, use non-blocking mode */
                    if (cam_context_p->snapshot_number > 1)
                    {
                        CAM_SET_EVENT(CAM_EVT_CAPTURE);
                    }
                    else
                    {
                        /* assign capture_buffer_p to MMI and assign file_size_p to MED Context for later use */
                        *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                        cam_context_p->file_size_p = req_p->file_size_p;
                    }
                #else /* MT6228_SERIES */
                    *req_p->file_size_p = cam_context_p->file_size;
                    *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                    /* close image fie */
                    CAM_ENTER_STATE(CAM_CAPTURE);
                    cam_set_result(MED_RES_OK);
                #if !MT6225_SERIES /* due to direct_couple and not encode yet, so do not free camera memory */
                    cam_release_memory();
                #endif
                    cam_release_af_lens_if_not_continuous_shot();
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                #endif /* MT6228_SERIES */
                }
                else if (req_p->source_device == CAM_SRC_MEM)
                {
                    cam_capture_from_layer(req_p);

                #if (MT6228_SERIES)
                    if (cam_context_p->capture_mem_result == LCD_OK)
                    {
                        CAM_ENTER_STATE(CAM_CAPTURE);
                        if (cam_context_p->snapshot_number > 1)
                        {
                            cam_context_p->jpeg_file_info_p = (jpegs_struct*) req_p->jpegs_p;
                            cam_context_p->jpeg_file_info_p->file_address[0] = cam_context_p->capture_buffer_p;
                            cam_context_p->jpeg_file_info_p->file_size[0] = img_context_p->file_size;
                            /* update buffer address and size for next shot */
                            jpg_encode.jpeg_file_start_address =
                                (kal_uint32) (cam_context_p->capture_buffer_p + img_context_p->file_size);
                            jpg_encode.jpeg_file_buffer_size -= img_context_p->file_size;
                            /* free internal mem for jpeg encode */
                            if (img_context_p->intmem_start_address)
                            {
                                med_free_int_mem((void **)&img_context_p->intmem_start_address);
                            	img_context_p->intmem_src = IMG_INTMEM_SRC_NONE;
                            }
                            CAM_SET_EVENT(CAM_EVT_CAPTURE);
                            cam_send_event_ind(CAM_EVT_CAPTURE, 1);
                        }
                        else
                        {
                            if (!req_p->manual_wb)
                            {
                                *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                                cam_context_p->file_size_p = req_p->file_size_p;
                                CAM_ENTER_STATE(CAM_CAPTURE);
                            }
                            else
                            {
                                cam_release_memory();
                                img_release_memory();
                                CAM_ENTER_STATE(CAM_READY);
                            }
                            cam_set_result(MED_RES_OK);
                            cam_release_af_lens_if_not_continuous_shot();
                            CAM_SET_EVENT(CAM_EVT_CAPTURE);
                        }
                    }
                    else
                    {
                        cam_context_p->continue_capture = KAL_FALSE;
                        if (cam_context_p->snapshot_number == 1)
                        {
                            cam_close_image_file(0);
                        }
                        cam_release_memory();
                        img_release_memory();
                        CAM_ENTER_STATE(CAM_READY);                   
                        cam_set_result(MED_RES_ERROR);
                        cam_release_af_lens_if_not_continuous_shot();
                        CAM_SET_EVENT(CAM_EVT_CAPTURE);
                    }
                #else /* MT6228_SERIES */
                    *req_p->capture_buffer_p = (void*)cam_context_p->capture_buffer_p;
                    cam_context_p->file_size_p = req_p->file_size_p;

                    CAM_ENTER_STATE(CAM_CAPTURE);
                    cam_set_result(MED_RES_OK);
                    cam_release_af_lens_if_not_continuous_shot();
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                #endif
                }
                else
                {
                    cam_release_af_lens_if_not_continuous_shot();
                    cam_set_result(MED_RES_ERROR);
                    CAM_ENTER_STATE(CAM_READY);
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                }
            }
            else
            {
                /* open image file fail */
                CAM_ENTER_STATE(CAM_READY);
                cam_set_result(result);
                cam_release_af_lens_if_not_continuous_shot();
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
        #endif /* MT6238_SERIES */
        }
        else
        {
            cam_set_result(MED_RES_INVALID_FORMAT);
            CAM_SET_EVENT(CAM_EVT_CAPTURE);
        }
    }
    else
    {
        cam_set_result(MED_RES_BUSY);
        CAM_SET_EVENT(CAM_EVT_CAPTURE);
    }
}

#define MED_CAM_FD_SEND_IND_TIME_DURATION (2)
#if defined(__MED_CAM_FD_SUPPORT__)
camera_fd_result_struct fd_result;
#endif

void cam_get_fd_result_req_hdlr(ilm_struct* ilm_ptr)
{
#if defined(__MED_CAM_FD_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_get_fd_result_struct *req_p;
    media_cam_fd_result_struct *fd_result_p;
    kal_int8 i;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;
    if (CAM_IN_STATE(CAM_PREVIEW) && cam_context_p->fd_enable == KAL_TRUE)
    {
        req_p = (media_cam_get_fd_result_struct*) ilm_ptr->local_para_ptr;
        fd_result_p = req_p->fd_result_p;
        
        fd_result_p->face_no = fd_result.face_no;
       
        for (i=0; i<fd_result_p->face_no; i++)
        {
            ASSERT (i<MAX_CAM_FD_NO);
            fd_result_p->id[i] = fd_result.id[i];                     
            fd_result_p->priority[i] = fd_result.priority[i];
            fd_result_p->rect_x0[i] = fd_result.rect_x0[i];
            fd_result_p->rect_x1[i] = fd_result.rect_x1[i];
            fd_result_p->rect_y0[i] = fd_result.rect_y0[i];
            fd_result_p->rect_y1[i] = fd_result.rect_y1[i];
        }
    }
    else
    {
        ASSERT(0);
    }
#endif /* __MED_CAM_FD_SUPPORT__ */

    CAM_SET_EVENT(CAM_EVT_BLOCK);
}

void cam_fd_process(void* args)
{
#if defined(__MED_CAM_FD_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int8 i;
    kal_uint8 priority;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_FD_IN_STATE(CAM_FD_STATE_STARTED) && CAM_IN_STATE(CAM_PREVIEW))
    {
        kal_uint8* fd_image_buffer_address;
        MED_CAM_START_LOGGING("CGI");        
        get_face_detection_image((kal_uint8**)&fd_image_buffer_address,0);
        MED_CAM_STOP_LOGGING("CGI");

        MED_CAM_START_LOGGING("CFP");
        camera_fd_process((kal_uint32)fd_image_buffer_address, &fd_result, KAL_FALSE, 0 /* don't care */);
        MED_CAM_STOP_LOGGING("CFP");

        cam_context_p->face_no = fd_result.face_no;

        /* to find the best fd id */
        if (cam_context_p->face_no != 0)
        {
            priority = fd_result.priority[0];
            cam_context_p->best_fd_id = fd_result.id[0];
            
            for (i=0; i<cam_context_p->face_no; i++)
            {
                ASSERT (i<MAX_CAM_FD_NO);
                if (fd_result.priority[i]>priority)
                    cam_context_p->best_fd_id = fd_result.id[i];
            }            
        }
        med_start_timer(CAM_FD_CAL_TIMER, CAM_FD_PROCESS_TIMEOUT_DURATION, cam_fd_process, 0);
    }
#endif /* #if defined(__MED_CAM_FD_SUPPORT__) */
}


void cam_set_fd_id_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

}


void cam_unset_fd_id_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

}


/*****************************************************************************
 * FUNCTION
 *  cam_start_fd_req_hdlr
 * DESCRIPTION
 *  This function is to resume fd process
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_resume_fd_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if defined(__MED_CAM_FD_SUPPORT__)
    switch(cam_context_p->fd_state)
    {
        case CAM_FD_STATE_STARTED:
            /* do nothing */
            cam_set_result(MED_RES_OK);
            break;

        case CAM_FD_STATE_PAUSED:
            /* load data into T-DCM */
            camera_fd_resume();
            /* start timer */
            med_start_timer(CAM_FD_CAL_TIMER, CAM_FD_PROCESS_TIMEOUT_DURATION, cam_fd_process, 0);
            CAM_FD_ENTER_STATE(CAM_FD_STATE_STARTED);
            cam_set_result(MED_RES_OK);        
            break;

        case CAM_FD_STATE_STOPPED:
            ASSERT(0);
            cam_set_result(MED_RES_FAIL);
            break;
    }
#endif /* #if defined(__MED_CAM_FD_SUPPORT__) */

    CAM_SET_EVENT(CAM_EVT_SET_PARAM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_pause_fd_req_hdlr
 * DESCRIPTION
 *  This function is to pause fd process
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_pause_fd_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if defined(__MED_CAM_FD_SUPPORT__)
    // enter pause state.
    switch(cam_context_p->fd_state)
    {
        case CAM_FD_STATE_STARTED:
            /* release data from T-DCM */
            camera_fd_pause();
            /* stop timer */
            med_stop_timer(CAM_FD_CAL_TIMER);
            CAM_FD_ENTER_STATE(CAM_FD_STATE_PAUSED);
            cam_set_result(MED_RES_OK);
            break;
        case CAM_FD_STATE_PAUSED:
            /* do nothing */
            cam_set_result(MED_RES_FAIL);
            break;
        case CAM_FD_STATE_STOPPED:
            ASSERT(0);
            break;
    }
#endif /* #if defined(__MED_CAM_FD_SUPPORT__) */
    CAM_SET_EVENT(CAM_EVT_SET_PARAM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_set_param_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera set parameter request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_set_param_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_set_param_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_set_param_req_struct*) ilm_ptr->local_para_ptr;

    if (CAM_IN_STATE(CAM_PREVIEW) || CAM_IN_STATE(CAM_CAPTURE) || CAM_IN_STATE(CAM_CAPTURE_BARCODE)
    #if defined(__MED_VID_ENC_MOD__) || defined(__MED_MJPG_ENC_MOD__)
        || VID_IN_STATE(VID_PREVIEW) || VID_IN_STATE(VID_RECORD) || VID_IN_STATE(VID_RECORD_PAUSED)
    #endif 
    #ifdef __MED_VCALL_MOD__
        || media_vall_is_cam_able_to_update_para()
    #endif
        )
    {
        if (req_p->param_id >= CAM_PARAM_ZOOM_FACTOR && req_p->param_id <= CAM_PARAM_EV_VALUE)
        {
        #if MT6238_SERIES 
            /* workaround for captured image's size too large when with effect, we need to remember current effect. */            
            if (req_p->param_id == CAM_PARAM_EFFECT)
                cam_context_p->image_effect = req_p->value;
        #endif

        /**
         * When fd is enabled, we should pause it to release T-DCM for zoom operation
         */
        #if defined(__MED_CAM_FD_SUPPORT__)
            if(CAM_FD_IN_STATE(CAM_FD_STATE_STARTED) && req_p->param_id == CAM_PARAM_ZOOM_FACTOR)
            {
                camera_fd_pause();
            }
        #endif /* defined(__MED_CAM_FD_SUPPORT__) */
        
            camera_image_setting((kal_uint8) req_p->param_id, (kal_uint16) req_p->value);

        #if defined(__MED_CAM_FD_SUPPORT__)
            if(CAM_FD_IN_STATE(CAM_FD_STATE_STARTED) && req_p->param_id == CAM_PARAM_ZOOM_FACTOR)
            {
                camera_fd_resume();
            }
        #endif /* defined(__MED_CAM_FD_SUPPORT__) */

        }
    #if (MT6228_SERIES || MT6238_SERIES || (MT6225_SERIES && !defined(MT6223P))|| (MT6219_SERIES&&!defined(MT6219)))
        else
        {
            kal_uint32 param_id = 255;

            switch (req_p->param_id)
            {

            #if MT6238_SERIES
                case CAM_PARAM_DSC_MODE:
                case CAM_PARAM_ISO:
                    param_id = CAM_DSC_MODE;
                break;
                case CAM_PARAM_AF_RANGE:
                    param_id = CAM_AF_RANGE;
                    break;
                case CAM_PARAM_AF_OPERATION:
                    param_id = CAM_AF_OPERATION_MODE;
                    break;
            #else /* MT6238_SERIES */
                case CAM_PARAM_ISO:
                    param_id = CAM_ISO;
                    cam_context_p->iso_setting = req_p->value;

                    if (cam_context_p->iso_setting == CAM_ISO_AUTO)
                    {
                        cam_context_p->dsc_mode = cam_context_p->prev_dsc_mode;
                        camera_operation_setting(CAM_DSC_MODE, cam_context_p->dsc_mode);
                    }
                    else
                    {
                        if (cam_context_p->af_mode == CAM_AF_AUTO_MODE)
                        {
                            camera_operation_setting(CAM_AF_MODE, CAM_AF_AUTO_MODE);
                        }
                        else if (cam_context_p->af_mode == CAM_AF_MACRO_MODE)
                        {
                            camera_operation_setting(CAM_AF_MODE, CAM_AF_MACRO_MODE);
                        }

                        /* SPECIAL CASE!  SET ISO VALUE FIRST, THEN SET DSC MODE TO ISO */
                        if (cam_context_p->dsc_mode != CAM_ISO_MODE)
                        {
                            cam_context_p->prev_dsc_mode = cam_context_p->dsc_mode;
                            cam_context_p->dsc_mode = CAM_ISO_MODE;
                            camera_operation_setting((kal_uint8) param_id, (kal_uint16) req_p->value);
                            camera_operation_setting(CAM_DSC_MODE, CAM_ISO_MODE);                            
                            CAM_SET_EVENT(CAM_EVT_SET_PARAM);
                            return;
                        }                        
                    }
                    break;
                case CAM_PARAM_AF_MODE:
                    param_id = CAM_AF_MODE;
                    cam_context_p->af_mode = req_p->value;
                    break;
                case CAM_PARAM_AF_METERING:
                    param_id = CAM_AF_METERING;
                    break;
                case CAM_PARAM_DSC_MODE:
                    param_id = CAM_DSC_MODE;                    
                    cam_context_p->prev_dsc_mode = cam_context_p->dsc_mode = req_p->value;
                    // adjust AF and ISO only in Camera Mode.
                    if (CAM_IN_STATE(CAM_PREVIEW) || CAM_IN_STATE(CAM_CAPTURE))
                    {
                        /* if dsc mode != night and iso != auto, apply af mode then iso setting */
                        if (req_p->value != CAM_NIGHTSCENE && cam_context_p->iso_setting != CAM_ISO_AUTO)
                        {
                            if (req_p->value == CAM_FLOWER) // MACRO MODE
                            {
                                cam_context_p->af_mode = CAM_AF_MACRO_MODE;
                                camera_operation_setting(CAM_AF_MODE, CAM_AF_MACRO_MODE);
                            }
                            else
                            {
                                cam_context_p->af_mode = CAM_AF_AUTO_MODE;
                                camera_operation_setting(CAM_AF_MODE, CAM_AF_AUTO_MODE);
                            }                            
                            camera_operation_setting(CAM_ISO, cam_context_p->iso_setting);
                            cam_context_p->dsc_mode = req_p->value = CAM_ISO_MODE;
                        }
                        else if (req_p->value != CAM_FLOWER)
                        {
                            cam_context_p->af_mode = CAM_AF_AUTO_MODE;
                            camera_operation_setting(CAM_AF_MODE, CAM_AF_AUTO_MODE);
                        }
                    }
                    break;
            #endif /* MT6238_SERIES */
                case CAM_PARAM_AF_KEY:
                    param_id = CAM_AF_KEY;
                    break;
                case CAM_PARAM_AE_METERING:
                    param_id = CAM_AE_METERING;
                    break;
                case CAM_PARAM_MANUAL_FOCUS_DIR:
                    param_id = CAM_MANUAL_FOCUS_DIR;
                    break;
                case CAM_PARAM_FLASH:
                    /* XENON FLASHLIGHT NOT USE camera_operation_setting interface */
                    #if defined(__MED_CAM_XENON_FLASH_SUPPORT__)
                        if (req_p->value == CAM_FLASH_OFF)
                        {
                            cam_turn_off_xenonflash();
                        }
                        else if (cam_context_p->xenon_flash_status == CAM_XENON_FLASH_OFF)
                        {
                            uem_bmt_struct bmt_status;
                            uem_get_bat_status(&bmt_status);
                            /* tmp solution for EVB */
                            if (bmt_status.volt == 0)
                                bmt_status.volt = 3700;
                            
                            if (bmt_status.volt < 3400)
                            {
                                cam_send_xenon_flash_status_ind(CAM_XENON_FLASH_LOW_BATTERY);
                            }                
                            else if(cam_turn_on_xenonflash()!=MED_RES_OK)
                                ASSERT(0);
                        }
                    #endif /* defined(__MED_CAM_XENON_FLASH_SUPPORT__) */
                    param_id = CAM_FLASH_MODE;
                    break;
                default:
                    ASSERT(0);
                    break;
            }

            camera_operation_setting((kal_uint8) param_id, (kal_uint16) req_p->value);
        }
    #endif /* MT6228_SERIES || MT6238_SERIES || MT6225_SERIES || (MT6219_SERIES&&!defined(MT6219)) */ 
    }
    else
    {
        cam_set_result(MED_RES_FAIL);
    }

    CAM_SET_EVENT(CAM_EVT_SET_PARAM);

}


/*****************************************************************************
 * FUNCTION
 *  cam_mwb_op_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera mwb require.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_mwb_op_req_hdlr(ilm_struct *ilm_ptr)
{
#if MT6228_SERIES
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_mwb_operation_req_struct *ind_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    ind_p = (media_cam_mwb_operation_req_struct*) ilm_ptr->local_para_ptr;
    switch (ind_p->op_type)
    {
        case CAM_MWB_ADJUST:
        {
            camera_mwb_process_struct mwb_para;

            mwb_para.mwb_buffer_address = ind_p->pmwb->mwb_buffer_address;
            mwb_para.mwb_image_height = ind_p->pmwb->mwb_image_height;
            mwb_para.mwb_image_width = ind_p->pmwb->mwb_image_width;
            camera_mwb_process(&mwb_para);
        }
            break;
        case CAM_MWB_BACKUP:
            backup_mwb_setting();
            break;
        case CAM_MWB_RESTORE:
            restore_mwb_setting();
            break;
        default:
            ASSERT(0) break;
    }
#endif /* MT6228_SERIES */
    CAM_SET_EVENT(CAM_EVT_MWB_OP);
}


/*****************************************************************************
 * FUNCTION
 *  cam_set_overlay_palette_req_hdlr
 * DESCRIPTION
 *  This function is to handle set overlay palette request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_set_overlay_palette_req_hdlr(ilm_struct *ilm_ptr)
{
#if (MT6228_SERIES)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_set_overlay_palette_req_struct *msg_p =
        (media_cam_set_overlay_palette_req_struct*) ilm_ptr->local_para_ptr;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
#if defined(DRV_IDP_OLD_DESIGN)
    set_overlay_palette(msg_p->palette_size, msg_p->palette_addr);
#else
    ASSERT(0);
#endif

#endif /* MT6228_SERIES */
    CAM_SET_EVENT(CAM_EVT_SET_PAL);
}


#if MT6238_SERIES
/*****************************************************************************
 * FUNCTION
 *  cam_capture_event_ind_hdlr
 * DESCRIPTION
 *  This function is to handle camera capture event indication.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
kal_int32 cam_capture_event_ind_hdlr(media_cam_event_ind_struct* ind_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    kal_int32 result = MED_RES_OK;
#if defined(__CAM_BSS_DEBUG_MODE__)
    FS_HANDLE file_handle;
    kal_uint32 len;
    kal_wchar file_name[512], idx[20];
#endif 
    kal_int32 curr_buff_size = 0;
    kal_int32 average_size = 0;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    MED_CAM_STOP_LOGGING("CPJ");
    MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_CAPTURE_JPEG_DURATION);

    med_stop_timer(CAM_CAPTURE_TIMEOUT_TIMER);

    if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        //@ Should add error handle case here.
        if (ind_p->cause == JPEG_CODEC_STATE_ERROR)
        {
            if (cam_context_p->snapshot_number == 1)
            {
                /* delete opened file handle and delete file */
                cam_close_image_file(0);

                /* if single shot, use blocking mode */
                cam_set_result(MED_RES_ERROR);
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
            else if (cam_context_p->special_capture_mode == CAM_CAPTURE_BEST_SHOT_MODE)
            {
                cam_context_p->capture_buffer_p = 0;
                cam_set_result(MED_RES_ERROR);
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
            else
            {
                /* non blocking mode */
                cam_send_capture_event_ind(MED_RES_ERROR, 0);
            }

            stop_camera_capture_process(CAM_INSUFFICIENT_BUFFER_STOP);
            cam_release_memory();
            CAM_ENTER_STATE(CAM_READY);
            return 0;
        }
        else if (ind_p->cause == JPEG_CODEC_STATE_COMPLETE)
        {
            cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1] = jpeg_capture_wrapper_get_encoded_length();
        }

    #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
    #endif /* defined(__MTK_INTERNAL__) */
        
        MED_CAM_START_LOGGING("SCC");
        stop_camera_capture_process(CAM_NORMAL_STOP);
        MED_CAM_STOP_LOGGING("SCC");

        if (cam_context_p->captured_number >= cam_context_p->snapshot_number || cam_context_p->snapshot_number == 1)
        {
            /* For avoiding the MED memory fragmentation, release memory in advance before panorama bg stitch allocates memory */
            cam_release_memory();
            
            if (cam_context_p->special_capture_mode == CAM_CAPTURE_BEST_SHOT_MODE) 
            {
                kal_uint8 best_shot;               

                cam_context_p->jpeg_file_info_p->file_address[cam_context_p->captured_number-1] = cam_context_p->capture_buffer_p;

                MED_CAM_GET_START_TIME(CAM_BSS_DURATION);
            
                best_shot = get_bss_result(cam_context_p->captured_number-1,cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]);
         
                MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_BSS_DURATION);

            #if defined(__CAM_BSS_DEBUG_MODE__)
                kal_wsprintf(idx, ".%d.jpg", cam_context_p->captured_number-1);
                kal_wstrcpy(file_name, cam_context_p->file_name_p);
                kal_wstrcat(file_name,idx);

                file_handle = FS_Open((kal_wchar*) file_name, FS_CREATE | FS_READ_WRITE);

                if (file_handle >= FS_NO_ERROR)
                {
                    result = FS_Write(file_handle, (void*)cam_context_p->capture_buffer_p, cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1], &len);
                    FS_Close(file_handle);
                    if ((result < FS_NO_ERROR)||(cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]!=len))
                    {
                        FS_Delete((kal_wchar*) file_name);
                    }
                }
            #endif /* __CAM_BSS_DEBUG_MODE__ */
                
                /* if latest one is not the best one, we need to change the best one back to capture_buffer_p*/
                /* When the last picture if captured, we need to save the best one in capture_buffer_p,
                 * due to save_req_hdlr treat capture_buffer_p as active working capture_buffer and best_capture_buffer_p will be freed immediately */
                if (best_shot != cam_context_p->captured_number-1)
                {
                    kal_uint32 temp_buffer_p;
                    temp_buffer_p = cam_context_p->best_capture_buffer_p;
                    cam_context_p->best_capture_buffer_p = cam_context_p->capture_buffer_p;
                    cam_context_p->capture_buffer_p = temp_buffer_p;
                }

                if (cam_context_p->capture_buffer_pp != NULL && cam_context_p->file_size_p != NULL)
                {
                   *(cam_context_p->capture_buffer_pp) = (void*)cam_context_p->capture_buffer_p;
                   *cam_context_p->file_size_p = cam_context_p->jpeg_file_info_p->file_size[best_shot];
                }
                cam_context_p->capture_buffer_p = 0;

            #if defined(__CAM_BSS_DEBUG_MODE__)
                kal_wsprintf(idx, ".%d.jpg", best_shot);
                kal_wstrcpy(file_name, cam_context_p->file_name_p);
                kal_wstrcat(file_name,idx);

                FS_Delete((kal_wchar*) file_name);
            #endif /* __CAM_BSS_DEBUG_MODE__ */
     
                cam_set_result(MED_RES_OK);
                cam_context_p->jpeg_file_info_p->file_size[0] = cam_context_p->jpeg_file_info_p->file_size[best_shot];
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
            else if ((cam_context_p->special_capture_mode == CAM_CAPTURE_BRACKET_EXPOSURE_MODE) || (cam_context_p->special_capture_mode == CAM_CAPTURE_BURST_SHOT_MODE))
            {
                cam_context_p->jpeg_file_info_p->file_address[cam_context_p->captured_number-1] = (kal_uint32)capture_isp_param.jpeg_enc_dst_buffer_addr;

                capture_isp_param.jpeg_enc_dst_buffer_size -= cam_context_p->jpeg_file_info.file_size[cam_context_p->captured_number-1];
                ASSERT(capture_isp_param.jpeg_enc_dst_buffer_size>0);

                /* for next time capture, we will not free this memory */
                cam_context_p->capture_buffer_p = 0;

                if (cam_context_p->special_capture_mode == CAM_CAPTURE_BRACKET_EXPOSURE_MODE)
                {
                    cam_set_result(result);
                    CAM_SET_EVENT(CAM_EVT_CAPTURE);
                }
            }
        #if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
            else if (cam_context_p->special_capture_mode == CAM_CAPTURE_PANORAMA_SHOT_MODE)
            {
                *cam_context_p->file_size_p = cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1];
                

                /* send background stitch request to media-v task */
                cam_v_send_start_bg_stitch_req(cam_context_p->current_shot_number,
                                               cam_context_p->direction,
                                               cam_context_p->jpeg_file_info_p->file_address[0],
                                               cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1],
                                               cam_context_p->image_width,
                                               cam_context_p->image_height);

                if (cam_context_p->captured_number == CAM_PANO_MAX_SHOT_NUM)
                {
                    cam_release_af_lens_if_not_continuous_shot();
                }
            }
        #endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */


            if (cam_context_p->special_capture_mode != CAM_CAPTURE_PANORAMA_SHOT_MODE)
            {
                cam_release_af_lens_if_not_continuous_shot();
            }
            #if 0
/* under construction !*/
            #endif
            if (cam_context_p->media_mode == MED_MODE_ARRAY)
            {
                CAM_ENTER_STATE(CAM_READY);
            }
        }
        else
        {
            if (cam_context_p->special_capture_mode == CAM_CAPTURE_BURST_SHOT_MODE) 
            {
                curr_buff_size = capture_isp_param.jpeg_enc_dst_buffer_size;
                average_size = curr_buff_size /(cam_context_p->snapshot_number - (cam_context_p->captured_number-1));
                
                cam_context_p->jpeg_file_info_p->file_address[cam_context_p->captured_number-1] = (kal_uint32)capture_isp_param.jpeg_enc_dst_buffer_addr;

                /* move pointer of capture buffer to the correct position */
                capture_isp_param.jpeg_enc_dst_buffer_size -= cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1];
                ASSERT(capture_isp_param.jpeg_enc_dst_buffer_size>0);
                capture_isp_param.jpeg_enc_dst_buffer_addr = (kal_uint8*)((kal_uint32) capture_isp_param.jpeg_enc_dst_buffer_addr + cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]); 

                if (cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1] > average_size)
                {
                    if (capture_isp_param.jpeg_enc_quality > CAM_JPG_QTY_LOW)
                    {
                        capture_isp_param.jpeg_enc_quality--;
                    }
                }
            }
            else if (cam_context_p->special_capture_mode == CAM_CAPTURE_BEST_SHOT_MODE) 
            {
                kal_uint8 best_shot;

                MED_CAM_GET_START_TIME(CAM_BSS_DURATION);

                best_shot = get_bss_result(cam_context_p->captured_number-1, cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]);

                MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_BSS_DURATION);

            #if defined(__CAM_BSS_DEBUG_MODE__)
                kal_wsprintf(idx, ".%d.jpg", cam_context_p->captured_number-1);
                kal_wstrcpy(file_name, cam_context_p->file_name_p);
                kal_wstrcat(file_name,idx);

                file_handle = FS_Open((kal_wchar*) file_name, FS_CREATE | FS_READ_WRITE);

                if (file_handle >= FS_NO_ERROR)
                {
                    result = FS_Write(file_handle, (void*)cam_context_p->capture_buffer_p, cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1], &len);
                    FS_Close(file_handle);
                    if ((result < FS_NO_ERROR)||(cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]!=len))
                    {
                        FS_Delete((kal_wchar*) file_name);
                    }
                }
            #endif /* __CAM_BSS_DEBUG_MODE__ */

                /* inbetween capturing, we save the best shot picture in best_capture_buffer_p */
                if (cam_context_p->captured_number == 1)
                {
                    cam_context_p->best_capture_buffer_p = cam_context_p->capture_buffer_p;
                    cam_context_p->capture_buffer_p += cam_context_p->capture_buffer_size; 
                }
                else
                {
                    /* check if latest one is best one */
                    if (best_shot == cam_context_p->captured_number-1)
                    {
                        kal_uint32 temp_buffer_p;
                        temp_buffer_p = cam_context_p->best_capture_buffer_p;
                        cam_context_p->best_capture_buffer_p = cam_context_p->capture_buffer_p;
                        cam_context_p->capture_buffer_p = temp_buffer_p;
                    }
                }

                capture_isp_param.jpeg_enc_dst_buffer_addr = (kal_uint8*) cam_context_p->capture_buffer_p;
                capture_isp_param.jpeg_enc_dst_buffer_size = cam_context_p->capture_buffer_size;    
            }
            else if (cam_context_p->special_capture_mode == CAM_CAPTURE_BRACKET_EXPOSURE_MODE)
            {
                cam_context_p->jpeg_file_info_p->file_address[cam_context_p->captured_number-1] = (kal_uint32)capture_isp_param.jpeg_enc_dst_buffer_addr;

                capture_isp_param.jpeg_enc_dst_buffer_size -= cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1];
                ASSERT(capture_isp_param.jpeg_enc_dst_buffer_size>0);
                capture_isp_param.jpeg_enc_dst_buffer_addr = (kal_uint8*)((kal_uint32) capture_isp_param.jpeg_enc_dst_buffer_addr + cam_context_p->jpeg_file_info_p->file_size[cam_context_p->captured_number-1]); 

                capture_isp_param.expo_bracket_level++;
            }

            /* SET snapshot to not_first */
            if (cam_context_p->captured_number == cam_context_p->snapshot_number - 1)
            {
                capture_isp_param.snapshot_number = MULTISHOT_END;
            }
            else
            {
                capture_isp_param.snapshot_number = MULTISHOT_NOT_FIRST;
            }

        #ifdef __MTK_TARGET__
            MED_CAM_GET_START_TIME(CAM_CAPTURE_JPEG_DURATION);
            MED_CAM_START_LOGGING("CPJ");
            med_start_timer(CAM_CAPTURE_TIMEOUT_TIMER, CAM_CAPTURE_TIMEOUT_DURATION, cam_capture_timeout_callback, 0);
            camera_capture_jpeg_process(&capture_isp_param);
        #endif
        }        

        if (cam_context_p->snapshot_number == 1)
        {
            if (cam_context_p->media_mode == MED_MODE_FILE)
            {
                if (cam_context_p->file_size_p != NULL)
                    *cam_context_p->file_size_p = cam_context_p->jpeg_file_info.file_size[0];
                //result = cam_close_image_file(cam_context_p->jpeg_file_info.file_size[0]);
            }
            else if (cam_context_p->media_mode == MED_MODE_ARRAY)
            {
                *cam_context_p->file_size_p = cam_context_p->jpeg_file_info.file_size[0];
            }
            else if (cam_context_p->media_mode == MED_MODE_BUFFER)
            {
                *cam_context_p->file_size_p = cam_context_p->jpeg_file_info.file_size[0];
                //result = cam_close_image_file(cam_context_p->jpeg_file_info.file_size[0]);
            }
            
            cam_set_result(MED_RES_OK);
            CAM_SET_EVENT(CAM_EVT_CAPTURE);
        }
        else
        {
            if (cam_context_p->special_capture_mode == CAM_CAPTURE_BURST_SHOT_MODE)
            {
                cam_send_capture_event_ind(MED_RES_OK, (kal_uint16) cam_context_p->captured_number);
            }          
        }

    }
    else if (cam_context_p->source_device == CAM_SRC_MEM)
    {
        ASSERT(0);
    }
    return 0;
}
#else /* MT6238_SERIES */
/*****************************************************************************
 * FUNCTION
 *  cam_capture_event_ind_hdlr
 * DESCRIPTION
 *  This function is to handle camera capture event indication.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
kal_int32 cam_capture_event_ind_hdlr(media_cam_event_ind_struct* ind_p)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    MED_CAM_STOP_LOGGING("CPJ");
    MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_CAPTURE_JPEG_DURATION);

    if (cam_context_p->source_device == CAM_SRC_ISP)
    {
        if (ind_p->cause == JPEG_ENCODE_BUFFER_FULL)
        {
            if (cam_context_p->snapshot_number == 1)
            {
                /* if single shot, use blocking mode */
                /* delete opened file handle and delete file */
                cam_close_image_file(0);
                
                cam_set_result(MED_RES_BUFFER_INSUFFICIENT);
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
            else
            {
                cam_send_capture_event_ind(MED_RES_BUFFER_INSUFFICIENT, 0);
            }
            stop_camera_capture_process();
            cam_release_memory();
            CAM_ENTER_STATE(CAM_READY);
        }
        else
        {
            if (cam_context_p->snapshot_number == 1)
            {
                /* if single shot, use blocking mode */
                if (cam_context_p->media_mode == MED_MODE_FILE)
                {
                    //DO NOTHING
                }
                else if (cam_context_p->media_mode == MED_MODE_ARRAY)
                {
                    ASSERT(0);
                    *cam_context_p->file_size_p = cam_context_p->jpeg_file_info.file_size[0];
                }
                else if (cam_context_p->media_mode == MED_MODE_BUFFER)
                {
                    *cam_context_p->file_size_p = cam_context_p->jpeg_file_info.file_size[0];
                }
            #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
            #endif
                cam_set_result(MED_RES_OK);
                CAM_SET_EVENT(CAM_EVT_CAPTURE);
            }
            else
            {
                cam_send_capture_event_ind(MED_RES_OK, (kal_uint16) ind_p->cause);
            }
            
            if (ind_p->cause >= cam_context_p->snapshot_number)
            {
                if ( cam_context_p->snapshot_number > 1 )
                {
                #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
                #endif
                    /* burst shot mode : set state to READY */
                    CAM_ENTER_STATE(CAM_READY);
                }

                stop_camera_capture_process();
                cam_release_memory();
            }
        }
    }
    else if (cam_context_p->source_device == CAM_SRC_MEM)
    {
        kal_uint8 shot_count;

        shot_count = ind_p->cause;
        /* step 1. get image from lcd layers to image buffer */

        #if defined(ISP_SUPPORT)
        capture_mem_param.intmem_start_address = cam_context_p->intmem_start_address =
            (kal_uint32) med_alloc_int_mem(cam_capture_mem[0]);
        capture_mem_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_capture_mem[0];
        #elif defined(__DIRECT_SENSOR_SUPPORT__)
        capture_mem_param.intmem_start_address= cam_context_p->intmem_start_address = (kal_uint32) med_alloc_int_mem(cam_capture_mem[0]);
        #endif

    #ifdef __MTK_TARGET__
        cam_context_p->capture_mem_result = camera_capture_mem_process(&capture_mem_param);
    #endif
        /* free internal mem for capture */
        if (cam_context_p->intmem_start_address)
        {
            med_free_int_mem((void **)&cam_context_p->intmem_start_address);
        }

        if (cam_context_p->capture_mem_result == LCD_OK)
        {
            /* step 2. encode image buffer to file */

            jpg_encode.intmem_size = img_context_p->intmem_size = MAX_IMG_ENC_INT_MEM_SIZE;
            if (MAX_IMG_ENC_INT_MEM_SIZE > 0)
            {
            	img_context_p->intmem_src = IMG_INTMEM_SRC_INTERNAL;        
                jpg_encode.intmem_start_address = img_context_p->intmem_start_address =
                    (kal_uint32) med_alloc_int_mem(MAX_IMG_ENC_INT_MEM_SIZE);
            }
            else
            {
                jpg_encode.intmem_start_address = img_context_p->intmem_start_address = 0;
            }

        #ifdef __MTK_TARGET__
            img_context_p->file_size = jpeg_encode_process(&jpg_encode);

            exit_jpeg_encode_process();
        #endif /* __MTK_TARGET__ */
            cam_context_p->jpeg_file_info_p->file_address[shot_count - 1] = jpg_encode.jpeg_file_start_address;
            cam_context_p->jpeg_file_info_p->file_size[shot_count - 1] = img_context_p->file_size;
            /* update buffer address and size for next shot */
            jpg_encode.jpeg_file_start_address =
                (kal_uint32) (jpg_encode.jpeg_file_start_address + img_context_p->file_size);
            jpg_encode.jpeg_file_buffer_size -= img_context_p->file_size;
            /* free internal mem for jpeg encode */
            if (img_context_p->intmem_start_address)
            {
                med_free_int_mem((void **)&img_context_p->intmem_start_address);
            	img_context_p->intmem_src = IMG_INTMEM_SRC_NONE;            
            }
            if (shot_count >= cam_context_p->snapshot_number)
            {
                cam_context_p->continue_capture = KAL_FALSE;
                cam_release_memory();
                img_release_memory();
                CAM_ENTER_STATE(CAM_READY);
            #if defined(__MTK_INTERNAL__)
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
            #endif
            }
            else
            {
                cam_send_event_ind(CAM_EVT_CAPTURE, (kal_uint8) (shot_count + 1));
            }

            cam_send_capture_event_ind(MED_RES_OK, (kal_uint16) shot_count);
        }
        else
        {
            cam_context_p->continue_capture = KAL_FALSE;
            cam_release_memory();
            img_release_memory();
            CAM_ENTER_STATE(CAM_READY);
            cam_send_capture_event_ind(MED_RES_ERROR, (kal_uint16) 0);
        }
    }
    return 0;
}
#endif

/*****************************************************************************
 * FUNCTION
 *  cam_event_ind_hdlr
 * DESCRIPTION
 *  This function is to handle camera event indication.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_event_ind_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_event_ind_struct *ind_p;


    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    ind_p = (media_cam_event_ind_struct*) ilm_ptr->local_para_ptr;

    if ((ind_p->event == CAM_EVT_PREVIEW) &&
        (CAM_IN_STATE(CAM_READY) || CAM_IN_STATE(CAM_PREVIEW) || CAM_IN_STATE(CAM_CAPTURE_BARCODE) ||
         (FACTORY_BOOT == stack_query_boot_mode())
    #ifdef __MED_VID_ENC_MOD__
         || VID_IN_STATE(VID_PREVIEW)
    #endif
        ))
    {
        /* auto adjust exposue value and white balance */
    #if defined(__MTK_TARGET__) && defined(ISP_SUPPORT) && !defined(YUV_SENSOR_SUPPORT) 
        ae_awb_main();
    #endif
    }
#ifdef __MED_WEBCAM_MOD__
    else if ((ind_p->event == CAM_EVT_PREVIEW) && (WEBCAM_IN_STATE(WEBCAM_PREVIEW)))
    {
        /* auto adjust exposue value and white balance */
    #if defined(__MTK_TARGET__) && !defined(YUV_SENSOR_SUPPORT) && !defined(__DIRECT_SENSOR_SUPPORT__)
        ae_awb_main();
    #endif
    }
#endif /* __MED_WEBCAM_MOD__ */
    else if ((ind_p->event == CAM_EVT_CAPTURE) && CAM_IN_STATE(CAM_CAPTURE))
    {
        cam_capture_event_ind_hdlr(ind_p);
    }
#if (defined(AF_SUPPORT) && ( MT6225_SERIES || (MT6219_SERIES && !defined(MT6219))|| (MT6228_SERIES || MT6238_SERIES)))
    else if ((ind_p->event == CAM_EVT_AUTOFOCUS))
    {
        if (FACTORY_BOOT == stack_query_boot_mode())
        {
            af_main();
        }
        else if ((CAM_IN_STATE(CAM_READY) || CAM_IN_STATE(CAM_PREVIEW)))
        {
            if (ind_p->cause == 0)
            {
                af_main();
            }
            else
            {
                #if MT6238_SERIES
                af_result_struct *af_result;
                af_result = get_af_result();

                cam_send_autofocus_process_done_ind(af_result->af_search_result, af_result->af_success_zone);
                #else
                cam_send_autofocus_process_done_ind(ind_p->event, (kal_uint32)ind_p->cause);
                #endif
            }
        }
    }
#endif /* defined(AF_SUPPORT) && ( MT6225_SERIES || (MT6219_SERIES && !defined(MT6219))|| (MT6228_SERIES || MT6238_SERIES)) */ 
#ifdef BARCODE_SUPPORT
    else if (ind_p->event == CAM_EVT_CAPTURE_BARCODE)
    {
        if (CAM_IN_STATE(CAM_READY))
        {
            media_cam_barcode_event_ind_struct barcode_event_ind;
            barcode_event_ind.event = ind_p->event;
            barcode_event_ind.cause = ind_p->cause;
            cam_send_barcode_decode_done_ind(&barcode_event_ind);
        }
        else
        {
            ASSERT(0);
        }
    }
#endif
}


/*****************************************************************************
 * FUNCTION
 *  cam_stitch_result_ind_hdlr
 * DESCRIPTION
 *  This function is to handle finish stitch panorama process indication from media-v
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stitch_result_ind_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_v_cam_stitch_result_ind_struct *ind_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    ind_p = (media_v_cam_stitch_result_ind_struct*) ilm_ptr->local_para_ptr;

    if (CAM_IN_STATE(CAM_STITCH))
    {
        cam_send_stitch_result_ind(ind_p->seq_no, ind_p->result,ind_p->jpeg_file_address, ind_p->jpeg_file_size,ind_p->jpeg_file_width,ind_p->jpeg_file_height);
        CAM_ENTER_STATE(CAM_READY);
    }
    else if (CAM_IN_STATE(CAM_STOPPING_STITCH))
    {
        /* MED is currently waiting stop cnf, the result ind is like stop cnf. */
        CAM_ENTER_STATE(CAM_READY);
        CAM_SET_EVENT(CAM_EVT_BLOCK);        
    }
    else if (CAM_IN_STATE(CAM_PAUSE_STITCH))
    {
        cam_context_p->is_stitch_done = KAL_TRUE;
        cam_context_p->stitch_seq_no = ind_p->seq_no;
        cam_context_p->stitch_result = ind_p->result ;
        cam_context_p->stitch_jpeg_file_address = ind_p->jpeg_file_address;
        cam_context_p->stitch_jpeg_file_size = ind_p->jpeg_file_size;
        cam_context_p->stitch_jpeg_file_width = ind_p->jpeg_file_width;
        cam_context_p->stitch_jpeg_file_height = ind_p->jpeg_file_height;
        CAM_ENTER_STATE(CAM_READY);
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* not reach here */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_start_stitch_req_hdlr
 * DESCRIPTION
 *  This function is to handle Start stitch Panorama Process request from MMI,
 *  it will send mesg to MED_V and wait indication from MED_V, then set event.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_start_stitch_req_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_start_stitch_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    // CAMERA_IN_STATE(READY)
    // Send start request to MED_V    
    // CAMERA_ENTER_STATE(STARTING_PANORAMA)
    if (CAM_IN_STATE(CAM_READY))
    {
        req_p = (media_cam_start_stitch_req_struct*) ilm_ptr->local_para_ptr;

        cam_context_p->stitch_session_id = req_p->seq_no;
    
        if (cam_context_p->captured_number < CAM_PANO_MAX_SHOT_NUM)
        {
            cam_release_af_lens_if_not_continuous_shot();
        }

        /* Send to MED_V */
        cam_v_send_start_stitch_req(req_p);

        /* enter STITCH state */
        CAM_ENTER_STATE(CAM_STITCH);

        /* set event */
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }
    else
    {
        ASSERT(0);
    }
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* not reach here */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_stop_stitch_req_hdlr
 * DESCRIPTION
 *  This function is to handle Stop stitch Panorama Process request from MMI,
 *  it will send mesg to MED_V and wait indication from MED_V, then set event.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stop_stitch_req_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    // CAMERA_IN_STATE(PANORAMA_PROCESS)
    // Send stop request to MED_V
    // CAMERA_ENTER_STATE(STOPPING_PANORAMA)
    if(CAM_IN_STATE(CAM_STITCH))
    {
        cam_v_send_stop_stitch_req();
        cam_context_p->stitch_session_id++;
        
        CAM_ENTER_STATE(CAM_STOPPING_STITCH);
    }
    else
    {
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }

#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* not reach here */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}



/*****************************************************************************
 * FUNCTION
 *  cam_reset_panorama_3a_req_hdlr
 * DESCRIPTION
 *  This function is to handle Stop stitch Panorama Process request from MMI,
 *  it will send mesg to MED_V and wait indication from MED_V, then set event.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_reset_panorama_3a_req_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    cam_context_p->is_stitch_done = KAL_FALSE;

    /* Send reset panorama req to media_v task and wait for cnf to set event*/
    cam_v_send_reset_panorama_req();

#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* not reach here */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}

/*****************************************************************************
 * FUNCTION
 *  cam_start_stitch_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle Indication message from MED_V, 
 *  when receive indication from MED_V, 
 *  it means that camera already entered panorama process state.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_start_stitch_cnf_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
}


/*****************************************************************************
 * FUNCTION
 *  cam_stop_stitch_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle Indication message from MED_V, 
 *  when receive indication from MED_V, 
 *  it means that panorama process already stopped.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_stop_stitch_cnf_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    if (CAM_IN_STATE(CAM_STOPPING_STITCH))
    {
        CAM_ENTER_STATE(CAM_READY);
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* not reach here */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_pause_stitch_req_hdlr
 * DESCRIPTION
 *  This function is to pause stitch process.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_pause_stitch_req_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    if (CAM_IN_STATE(CAM_STITCH))
    {
        CAM_ENTER_STATE(CAM_PAUSE_STITCH);
        cam_v_send_pause_stitch_req();
    }
    else
    {
        cam_set_result(MED_RES_FAIL);
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* should not reach here! */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_pause_stitch_cnf_hdlr
 * DESCRIPTION
 *  This function is to handler th pause stitch confirm msg from media-v
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_pause_stitch_cnf_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_PAUSE_STITCH))
    {
        CAM_ENTER_STATE(CAM_READY);
        cam_set_result(MED_RES_OK);
        CAM_SET_EVENT(CAM_EVT_BLOCK);
    }
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* should not reach here! */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_resume_stitch_req_hdlr
 * DESCRIPTION
 *  This function is to pause stitch process.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_resume_stitch_req_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    if (CAM_IN_STATE(CAM_READY))
    {
        if (cam_context_p->is_stitch_done == KAL_TRUE)
        {
            cam_send_stitch_result_ind(cam_context_p->stitch_seq_no, 
                                       cam_context_p->stitch_result,
                                       cam_context_p->stitch_jpeg_file_address, 
                                       cam_context_p->stitch_jpeg_file_size,
                                       cam_context_p->stitch_jpeg_file_width,
                                       cam_context_p->stitch_jpeg_file_height);
            cam_context_p->is_stitch_done = KAL_FALSE;
        }
        else
        {
            CAM_ENTER_STATE(CAM_STITCH);
            cam_v_send_resume_stitch_req();
        }
    }
    else
    {
        cam_set_result(MED_RES_FAIL);
    }

    CAM_SET_EVENT(CAM_EVT_BLOCK);
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* should not reach here! */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    
}


/*****************************************************************************
 * FUNCTION
 *  cam_resume_stitch_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle resume stitch confirm mesg from media-v.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_resume_stitch_cnf_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/

    /* do nothing. */
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* should not reach here! */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    
}


 /*****************************************************************************
 * FUNCTION
 *  cam_reset_panorama_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle reset panarama confirm mesg from media-v.
 * PARAMETERS
 *  ilm_ptr     [in]  ilm struct
 * RETURNS
 *  void
 *****************************************************************************/
void cam_reset_panorama_cnf_hdlr(ilm_struct *ilm_ptr)
{
#if defined(__MED_CAM_PANORAMA_VIEW_SUPPORT__)
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_set_result(MED_RES_OK);
    CAM_SET_EVENT(CAM_EVT_BLOCK);
#else /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
    /* should not reach here! */
    ASSERT(0);
#endif /* __MED_CAM_PANORAMA_VIEW_SUPPORT__ */
}


/*****************************************************************************
 * FUNCTION
 *  cam_abort_to_idle
 * DESCRIPTION
 *  This function is to abort all operations and go to idle state .
 * PARAMETERS
 *  void
 * RETURNS
 *  void
 *****************************************************************************/
void cam_abort_to_idle(void)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_PREVIEW))
    {
    #ifdef __MTK_TARGET__
        exit_camera_preview_process();
        cam_release_memory();
        CAM_ENTER_STATE(CAM_READY);
        #if defined(ISP_SUPPORT)
            power_off_isp();
        #elif defined(__DIRECT_SENSOR_SUPPORT)
            camera_exit();
        #endif
    #endif /* __MTK_TARGET__ */
        /* to release the memory allocated in MED_MODE_BUFFER mode */
        CAM_FREE_CAPTURE_BUFFER();
        CAM_ENTER_STATE(CAM_IDLE);
    }
    else if (CAM_IN_STATE(CAM_CAPTURE))
    {
    #ifdef __MTK_TARGET__
    #if MT6238_SERIES
        med_stop_timer(CAM_CAPTURE_TIMEOUT_TIMER);
        stop_camera_capture_process(CAM_CAPTURE_TIME_OUT_STOP);
    #else
        stop_camera_capture_process();
    #endif
        cam_release_memory();
        CAM_ENTER_STATE(CAM_READY);
        #if defined(ISP_SUPPORT)
            power_off_isp();
        #elif defined(__DIRECT_SENSOR_SUPPORT)
            camera_exit();
        #endif
    #endif /* __MTK_TARGET__ */
        /* to release the memory allocated in MED_MODE_BUFFER mode */
        CAM_FREE_CAPTURE_BUFFER();
        CAM_ENTER_STATE(CAM_IDLE);
        CAM_SET_EVENT(CAM_EVT_CAPTURE);
    }
    else if (CAM_IN_STATE(CAM_READY))
    {
    #ifdef __MTK_TARGET__
        #if defined(ISP_SUPPORT)
            power_off_isp();
        #elif defined(__DIRECT_SENSOR_SUPPORT)
            camera_exit();
        #endif
    #endif
        /* to release the memory allocated in MED_MODE_BUFFER mode */
        CAM_FREE_CAPTURE_BUFFER();
        CAM_ENTER_STATE(CAM_IDLE);
    }
}

#if defined(BARCODE_SUPPORT)
/*****************************************************************************
 * FUNCTION
 *  cam_barcode_callback
 * DESCRIPTION
 *  This function is to handle camera focus callback.
 * PARAMETERS
 *  cause       [IN]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_callback(kal_uint8 cause)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    /* cam_send_barcode_decode_done_ind(cause); */
}


/*****************************************************************************
 * FUNCTION
 *  cam_barcode_preview_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera preview request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_preview_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_preview_req_struct *req_p;
    camera_capture_barcode_struct preview_param;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_READY))
    {
        CAM_FREE_BARCODE_BUFFER();
        req_p = (media_cam_preview_req_struct*) ilm_ptr->local_para_ptr;
        cam_context_p->lcd_id = preview_param.lcd_id = req_p->lcd_id;
        cam_context_p->lcd_start_x = preview_param.lcm_start_x = req_p->lcd_start_x;
        cam_context_p->lcd_start_y = preview_param.lcm_start_y = req_p->lcd_start_y;
        cam_context_p->lcd_end_x = preview_param.lcm_end_x = req_p->lcd_end_x;
        cam_context_p->lcd_end_y = preview_param.lcm_end_y = req_p->lcd_end_y;
        cam_context_p->roi_offset_x = preview_param.roi_offset_x = req_p->roi_offset_x;
        cam_context_p->roi_offset_y = preview_param.roi_offset_y = req_p->roi_offset_y;
        cam_context_p->update_layer = preview_param.update_layer = req_p->update_layer;
        cam_context_p->hw_update_layer = preview_param.hw_update_layer = req_p->hw_update_layer;


        preview_param.intmem_start_address = cam_context_p->intmem_start_address =
            (kal_uint32) med_alloc_int_mem(cam_preview_mem[0]);
        preview_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_preview_mem[0];
        preview_param.extmem_start_address = 0;
        preview_param.extmem_size = 0;
        preview_param.target_width = req_p->image_width;
        preview_param.target_height = req_p->image_height;


        preview_param.source_width = cam_context_p->preview_width = req_p->preview_width;
        preview_param.source_height = cam_context_p->preview_height = req_p->preview_height;
        /* use internal memory for preview buffer if enough */
    #if (MT6238_SERIES || MT6228_SERIES)
        if (req_p->image_buffer_size * 2 + MEM_OVERHEAD  < med_int_left_size() )
        {
            /* internal memory enough for double buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            cam_context_p->int_frame_buffer_p = preview_param.frame_buffer_address =
                (kal_uint32) med_alloc_int_mem(preview_param.frame_buffer_size * 2);
            preview_param.frame_buffer_address1 = preview_param.frame_buffer_address + preview_param.frame_buffer_size;
            cam_context_p->ext_frame_buffer_p = 0;
        }
        else
    #endif
        if (req_p->image_buffer_size + MEM_OVERHEAD < med_int_left_size() )
        {
            /* internal memory enough for single buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            /* one internal buffer */
            cam_context_p->int_frame_buffer_p = preview_param.frame_buffer_address =
                (kal_uint32) med_alloc_int_mem(preview_param.frame_buffer_size);
            /* one external buffer */
            preview_param.frame_buffer_address1 = cam_context_p->frame_buffer_p;
            cam_context_p->ext_frame_buffer_p = 0;
        }
        else if (req_p->image_buffer_size + MEM_OVERHEAD < med_ext_left_size() )
        {
            /* internal memory enough for single buffer */
            cam_context_p->frame_buffer_p = (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = cam_context_p->extmem_size = preview_param.frame_buffer_size =
                preview_param.frame_buffer_size1 = req_p->image_buffer_size;
            /* one external buffer given from MMI */
            preview_param.frame_buffer_address = cam_context_p->frame_buffer_p;
            /* one more external buffer */
            cam_context_p->ext_frame_buffer_p = preview_param.frame_buffer_address1 =
                (kal_uint32) med_alloc_ext_mem(preview_param.frame_buffer_size);
            cam_context_p->int_frame_buffer_p = 0;
        }
        else
        {
            /* use single external buffer from MMI */
            cam_context_p->frame_buffer_p = preview_param.frame_buffer_address1 = preview_param.frame_buffer_address =
                (kal_uint32) req_p->image_buffer_p;
            cam_context_p->frame_buffer_size = preview_param.frame_buffer_size1 = preview_param.frame_buffer_size =
                req_p->image_buffer_size;
            cam_context_p->int_frame_buffer_p = 0;
            cam_context_p->ext_frame_buffer_p = 0;
        }

        cam_context_p->barcode_buffer_size = preview_param.barcode_buffer_size =
            req_p->image_width * req_p->image_height * 2;
        cam_context_p->barcode_buffer_address = preview_param.barcode_buffer_address =
            (kal_uint32) med_alloc_ext_mem(cam_context_p->barcode_buffer_size);
        cam_context_p->barcode_buffer_width = req_p->image_width;
        cam_context_p->barcode_buffer_height = req_p->image_height;

        ASSERT(cam_context_p->barcode_buffer_address != NULL);

        cam_context_p->ev_value = preview_param.ev_value = req_p->exposure;
#if !MT6238_SERIES
        cam_context_p->zoom_factor = preview_param.zoom_factor = req_p->zoom_factor;
#endif        
        cam_context_p->image_mirror = preview_param.image_mirror = cam_rotate_map[req_p->rotate];
        cam_context_p->banding_freq = preview_param.banding_freq = req_p->banding_freq;
        cam_context_p->lcd_rotate = req_p->lcd_rotate;
        preview_param.frame_rate = cam_context_p->frame_rate = cam_get_preview_frame_rate(req_p->frame_rate);

        /* preview_param.rotate_value=(kal_uint8)req_p->lcd_rotate; */
        /* LCD Setting */
        /* cam_context_p->roi_background_color=preview_param.roi_background_color=req_p->roi_background_color; */

        /* AF */
    #if defined(__CAM_AUTO_FOCUS__) && !MT6238_SERIES
        cam_context_p->camera_offset_x = preview_param.camera_offset_x = req_p->camera_offset_x;
        cam_context_p->camera_offset_y = preview_param.camera_offset_y = req_p->camera_offset_y;
        cam_context_p->af_zone0_x = preview_param.af_zone0_x = req_p->af_zone0_x;
        cam_context_p->af_zone0_y = preview_param.af_zone0_y = req_p->af_zone0_y;
        cam_context_p->af_zone1_x = preview_param.af_zone1_x = req_p->af_zone1_x;
        cam_context_p->af_zone1_y = preview_param.af_zone1_y = req_p->af_zone1_y;
        cam_context_p->af_zone2_x = preview_param.af_zone2_x = req_p->af_zone2_x;
        cam_context_p->af_zone2_y = preview_param.af_zone2_y = req_p->af_zone2_y;
        cam_context_p->af_zone3_x = preview_param.af_zone3_x = req_p->af_zone3_x;
        cam_context_p->af_zone3_y = preview_param.af_zone3_y = req_p->af_zone3_y;
        cam_context_p->af_zone4_x = preview_param.af_zone4_x = req_p->af_zone4_x;
        cam_context_p->af_zone4_y = preview_param.af_zone4_y = req_p->af_zone4_y;
    #endif /* defined(__CAM_AUTO_FOCUS__) && !MT6238_SERIES */

    #if MT6238_SERIES
        /* this should be passed by MMI */
        preview_param.zoom_step = 0;
        preview_param.max_zoom_factor = 800;
        preview_param.total_zoom_step = 40;

        cam_context_p->preview_rotate_value = preview_param.preview_rotate_value = req_p->preview_rotate_value;
        preview_param.barcode_image_data_format = IMG_COLOR_FMT_RGB565;

        cam_context_p->dummy_barcode_buffer_address = preview_param.dummy_barcode_buffer_address =
            (kal_uint32) med_alloc_ext_mem(cam_context_p->barcode_buffer_size);

        ASSERT(cam_context_p->dummy_barcode_buffer_address != NULL);
        
        cam_context_p->image_pitch_mode = preview_param.image_pitch_mode = req_p->image_pitch_mode;
        cam_context_p->image_data_format = preview_param.image_data_format = req_p->image_data_format;
        cam_context_p->image_pitch_bytes = preview_param.image_bg_image_width = req_p->image_bg_image_width;
        cam_context_p->rot_angle = preview_param.rot_angle = req_p->rot_angle;
    #elif MT6228_SERIES
        preview_param.barcode_image_data_format = IMGDMA_IBW_OUTPUT_RGB565;
        /* IPP Setting */
        cam_context_p->image_pitch_mode = preview_param.image_pitch_mode = req_p->image_pitch_mode;
        cam_context_p->image_data_format = preview_param.image_data_format = req_p->image_data_format;
        cam_context_p->image_pitch_bytes = preview_param.image_pitch_bytes = req_p->image_pitch_bytes;
    #endif

    #ifdef __MED_TVO_MOD__
        tvo_context_p->tv_output_mode = req_p->tv_output_mode;
        tvo_context_p->tv_output = preview_param.tv_output = req_p->tv_output;
        tvo_context_p->tv_output_width = preview_param.tv_output_width = req_p->tv_output_width;
        tvo_context_p->tv_output_height = preview_param.tv_output_height = req_p->tv_output_height;
        tvo_context_p->tv_output_offset_x = preview_param.tv_output_offset_x = req_p->tv_output_offset_x;
        tvo_context_p->tv_output_offset_y = preview_param.tv_output_offset_y = req_p->tv_output_offset_y;
        tvo_context_p->tv_output_buffer_size = preview_param.tv_output_buffer_size = req_p->tv_output_buffer_size;
        tvo_context_p->tv_output_buffer1_address = preview_param.tv_output_buffer1_address = req_p->tv_output_buffer1_address;
        tvo_context_p->tv_output_buffer2_address = preview_param.tv_output_buffer2_address = req_p->tv_output_buffer2_address;
    #endif /* __MED_TVO_MOD__ */

        preview_param.cam_preview_cb = cam_preview_callback;
        preview_param.cam_focus_cb = cam_focus_callback;

        preview_param.cam_capture_barcode_cb = cam_barcode_callback;

    #ifdef __MTK_TARGET__
        if (camera_capture_barcode_process(&preview_param) != KAL_TRUE)
        {
            /* preview failed, free memory and power off camera */
            cam_release_memory();
            #if defined(ISP_SUPPORT)
                power_off_isp();
            #elif defined(__DIRECT_SENSOR_SUPPORT)
                camera_exit();
            #endif
            /* to release the memory allocated in MED_MODE_BUFFER mode */
            CAM_FREE_CAPTURE_BUFFER();
            CAM_ENTER_STATE(CAM_IDLE);
            cam_set_result(MED_RES_FAIL);
        }
        else
    #endif /* __MTK_TARGET__ */
        {
            CAM_ENTER_STATE(CAM_PREVIEW);
        }

    }
    else
    {
        cam_set_result(MED_RES_BUSY);
    }

    CAM_SET_EVENT(CAM_EVT_PREVIEW);

}


/*****************************************************************************
 * FUNCTION
 *  cam_barcode_stop_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera stop request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_stop_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_PREVIEW))
    {
    #ifdef __MTK_TARGET__
        stop_camera_capture_barcode_process();
    #endif
        cam_release_memory();
        img_release_memory();
        CAM_FREE_BARCODE_BUFFER();
        CAM_ENTER_STATE(CAM_READY);
    }
    else if (CAM_IN_STATE(CAM_CAPTURE_BARCODE))
    {
        med_stop_timer(CAM_BARCODE_DECODE_TIMER);
        stop_camera_capture_barcode_process();
        cam_release_memory();
        img_release_memory();
        CAM_FREE_BARCODE_BUFFER();
        CAM_ENTER_STATE(CAM_READY);
    }
    else
    {
        cam_release_memory();
        img_release_memory();
        CAM_FREE_BARCODE_BUFFER();
    }

    CAM_SET_EVENT(CAM_EVT_STOP);

}


/*****************************************************************************
 * FUNCTION
 *  cam_barcode_capture_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera capture request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_capture_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_barcode_capture_struct *req_p;


    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_barcode_capture_struct*) ilm_ptr->local_para_ptr;
    cam_context_p->barcode_text_buf_address = (kal_uint8*) req_p->text_buf;
    cam_context_p->barcode_text_buf_length = req_p->buf_length;
    cam_context_p->barcode_type = req_p->barcode_type;
    if (CAM_IN_STATE(CAM_PREVIEW))
    {
        CAM_ENTER_STATE(CAM_CAPTURE_BARCODE);
    #ifdef __MTK_TARGET__
        cam_barcode_capture_and_decode(NULL);
    #endif

    }
    else
    {
        ASSERT(0);
    }
    CAM_SET_EVENT(CAM_EVT_CAPTURE_BARCODE);
}


/*****************************************************************************
 * FUNCTION
 *  cam_barcode_stop_capture_req_hdlr
 * DESCRIPTION
 *  This function is to handle camera capture request.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_stop_capture_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_CAPTURE_BARCODE))
    {

    #ifdef __MTK_TARGET__
    #if defined(AF_SUPPORT)
        if (cam_context_p->af_mode != CAM_AF_MANUAL_MODE)
            camera_operation_setting((kal_uint8) CAM_AF_KEY, (kal_uint16) CAM_AF_RELEASE);
    #endif
        med_stop_timer(CAM_BARCODE_DECODE_TIMER);
    #endif /* __MTK_TARGET__ */
        CAM_ENTER_STATE(CAM_PREVIEW);
    }

    CAM_SET_EVENT(CAM_EVT_STOP_CAPTURE_BARCODE);

}

#if defined(BARCODE_DECODER_GMEDIA_QRDM) || defined(BARCODE_DECODER_GMEDIA_DM)
/*****************************************************************************
 * FUNCTION
 *  med_prompt_trace
 * DESCRIPTION
 *  This function is printout trace 
 * PARAMETERS
 *  args        [?]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void med_prompt_trace(char *args)
{
    kal_wap_trace(MOD_MED,TRACE_INFO,args);
}

/*****************************************************************************
 * FUNCTION
 *  cam_barcode_capture_and_decode
 * DESCRIPTION
 *  This function is to handle camera capture request.
 * PARAMETERS
 *  args        [?]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_capture_and_decode(void *args)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    unsigned char *pucResultCode;
    int piCodeNumbers;
    int pnSymbolsIndex;
    int pnSymbolsNumbers;
    int pnSymbolType;
    kal_int32 string_length;
    kal_int32 status = 0;
    media_cam_barcode_event_ind_struct barcode_event_ind;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_CAPTURE_BARCODE))
    {
    #ifdef __MTK_TARGET__
        get_barcode_image();

    #if ((MT6219_SERIES && !defined(MT6219)) && defined(DYNAMIC_CODE_MANAGER))
        DCM_Load( DYNAMIC_CODE_BCODE, NULL, NULL);
    #endif
       
    status = Barcode_Decode(
                (unsigned char *)cam_context_p->barcode_buffer_address,
                cam_context_p->barcode_buffer_width, 
                cam_context_p->barcode_buffer_height,
                GMEDIA_IMAGE_FORMAT_RGB565,
                cam_context_p->barcode_text_buf_address,
                cam_context_p->barcode_text_buf_length,
                &piCodeNumbers, 
                &pnSymbolsIndex,
                &pnSymbolsNumbers,
                &pnSymbolType);

    #if ((MT6219_SERIES && !defined(MT6219)) && defined(DYNAMIC_CODE_MANAGER))
        DCM_Unload(DYNAMIC_CODE_BCODE);
    #endif

        /*********************************************************************
         *
         *  check if it is appended QR Code
         *
         ********************************************************************/
        if (status > 0)
        {
            barcode_event_ind.event = (kal_uint16)CAM_EVT_CAPTURE_BARCODE;
            barcode_event_ind.cause = (kal_uint8)MED_RES_OK;
            barcode_event_ind.encoding = 0;

            if (pnSymbolsNumbers==0)
            barcode_event_ind.nsymbol = 1;
            else
            barcode_event_ind.nsymbol = pnSymbolsNumbers;
            
            barcode_event_ind.symbolid = pnSymbolsIndex;
            barcode_event_ind.paritydata = 0;
            switch(pnSymbolType)
            {
               case GMEDIA_BARCODE_TYPE_QR:
            	barcode_event_ind.barcode_type = 1;
            	break;
            	case GMEDIA_BARCODE_TYPE_DM:
            	barcode_event_ind.barcode_type = 2;
            	break;
            	case GMEDIA_BARCODE_TYPE_UNKNOWN:
            	barcode_event_ind.barcode_type = 0;
            	break;
            }
   
            #if defined(AF_SUPPORT)
            camera_operation_setting((kal_uint8) CAM_AF_KEY, (kal_uint16) CAM_AF_RELEASE);
            #endif
            stop_camera_capture_barcode_process();
            cam_release_memory();
            img_release_memory();
            CAM_FREE_BARCODE_BUFFER();

            cam_send_barcode_decode_done_ind(&barcode_event_ind);

            CAM_ENTER_STATE(CAM_READY);
        }        
        else
        {
            CAM_QR_RESULT_TRACE(status);
            barcode_event_ind.event = (kal_uint16)CAM_EVT_CAPTURE_BARCODE;
            barcode_event_ind.encoding = 0;
            barcode_event_ind.nsymbol = 0;
            barcode_event_ind.symbolid = 0;
            barcode_event_ind.paritydata = 0;

            med_start_timer(CAM_BARCODE_DECODE_TIMER, 100, cam_barcode_capture_and_decode, 0);
#if 0
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
            #if defined(AF_SUPPORT)
/* under construction !*/
            #endif
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
/* under construction !*/
#endif

        }
    #ifdef __MED_BARCODE_TEST__
        FREE_MEM_SCANBUY(retVal);
    #endif

    #endif /* __MTK_TARGET__ */
    }
    else
    {
        ASSERT(0);
    }
}

#elif defined(BARCODE_DECODER_SCANBUY_QRDM) || defined(BARCODE_DECODER_SCANBUY_DM)
/*****************************************************************************
 * FUNCTION
 *  cam_barcode_capture_and_decode
 * DESCRIPTION
 *  This function is to handle camera capture request.
 * PARAMETERS
 *  args        [?]
 *  ilm_struct *ilm_ptr(?)
 * RETURNS
 *  void
 *****************************************************************************/
void cam_barcode_capture_and_decode(void *args)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    sc2dBarcode *psc2dBcd = NULL;
    kal_int32 string_length;
    kal_int32 status = 0;
    media_cam_barcode_event_ind_struct barcode_event_ind;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_CAPTURE_BARCODE))
    {
    #ifdef __MTK_TARGET__
        MED_CAM_GET_START_TIME(CAM_BARCODE_GET_IMAGE_DURATION);
        MED_CAM_START_LOGGING("BGI");
        get_barcode_image();
        MED_CAM_STOP_LOGGING("BGI");
        MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_BARCODE_GET_IMAGE_DURATION);
        //Generating structure
        psc2dBcd = sc2dDecoder_New();
        if (psc2dBcd == NULL){
            ASSERT(0);
        }        


    #if (MT6219_SERIES && !defined(MT6219))
        DCM_Load( DYNAMIC_CODE_BCODE, NULL, NULL);
    #endif

    status = sc2dDecoder_SetInput(psc2dBcd,
                                  (TUint8*)cam_context_p->barcode_buffer_address,
                                  SC_IMG_RGB565,//SC_IMG_RGB888,//SC_IMG_RGB565,//SC_IMG_GRAY,
                                  (TUint32)cam_context_p->barcode_buffer_width,
                                  (TUint32)cam_context_p->barcode_buffer_height,
                                  (TUint32)cam_context_p->barcode_type);

   

    if (status != SC_2D_SUCCESS)
    {
        scFree2dBarcode(&psc2dBcd);
    }
    else
    {
        MED_CAM_GET_START_TIME(CAM_BARCODE_DECODE_DURATION);
        MED_CAM_START_LOGGING("BCD");
        status = sc2dDecoder_Process(psc2dBcd);
        MED_CAM_STOP_LOGGING("BCD");
        MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_BARCODE_DECODE_DURATION);
    }

    #if (MT6219_SERIES && !defined(MT6219))
        DCM_Unload(DYNAMIC_CODE_BCODE);
    #endif

        /*********************************************************************
         *
         *  check if it is appended QR Code
         *
         ********************************************************************/
        if (status ==SC_2D_SUCCESS)
        {
            barcode_event_ind.event = (kal_uint16)CAM_EVT_CAPTURE_BARCODE;
            barcode_event_ind.cause = (kal_uint8)MED_RES_OK;
            barcode_event_ind.encoding = 0;
            barcode_event_ind.nsymbol = 1;
            barcode_event_ind.symbolid = 1;
            barcode_event_ind.paritydata = 0;
            barcode_event_ind.barcode_type = psc2dBcd->retType;

            string_length = (psc2dBcd->retLength > cam_context_p->barcode_text_buf_length - 2)?
                (cam_context_p->barcode_text_buf_length - 2) : psc2dBcd->retLength;
            memcpy(cam_context_p->barcode_text_buf_address,psc2dBcd->retVal,string_length);
            cam_context_p->barcode_text_buf_address[string_length] = 0;
            cam_context_p->barcode_text_buf_address[string_length+1] = 0;
            
            #if defined(AF_SUPPORT)
            camera_operation_setting((kal_uint8) CAM_AF_KEY, (kal_uint16) CAM_AF_RELEASE);
            #endif
            stop_camera_capture_barcode_process();
            cam_release_memory();
            img_release_memory();
            CAM_FREE_BARCODE_BUFFER();
            
            if (psc2dBcd->retType == SC_2D_QR)
            {
                barcode_event_ind.encoding = psc2dBcd->pQR->encodeMode;
                barcode_event_ind.nsymbol = psc2dBcd->pQR->nSymbols;
                barcode_event_ind.symbolid = psc2dBcd->pQR->symbolId;
                barcode_event_ind.paritydata = psc2dBcd->pQR->parityData;
            }
            
            cam_send_barcode_decode_done_ind(&barcode_event_ind);

            CAM_ENTER_STATE(CAM_READY);
            sc2dDecoder_Clean(psc2dBcd);
            scFree2dBarcode(&psc2dBcd);	
        }
        else
        {
            CAM_QR_RESULT_TRACE(status);
            barcode_event_ind.event = (kal_uint16)CAM_EVT_CAPTURE_BARCODE;
            barcode_event_ind.encoding = 0;
            barcode_event_ind.nsymbol = 0;
            barcode_event_ind.symbolid = 0;
            barcode_event_ind.paritydata = 0;

            if (status == SC_2D_EFAILED)
            {
                med_start_timer(CAM_BARCODE_DECODE_TIMER, 100, cam_barcode_capture_and_decode, 0);
                sc2dDecoder_Clean(psc2dBcd);
                scFree2dBarcode(&psc2dBcd);
            }
            else
            {
                switch (status)
                {
                    case SC_2D_EIMGSIZE:
                        barcode_event_ind.cause = (kal_uint8)MED_RES_BR_MODULE_ERROR;
                    break;
                    case SC_2D_ENOMEMORY:
                        barcode_event_ind.cause = (kal_uint8)MED_RES_BR_OUT_OF_MEMORY;
                    break;
                    case SC_2D_EVERSIONNOTSUPPORT:
                    case SC_2D_EQRVERSION2HIGH:
                        barcode_event_ind.cause = (kal_uint8)MED_RES_BR_OVER_VERSION;
                    break;
                    case SC_2D_ECODETYPE:
                        barcode_event_ind.cause = (kal_uint8)MED_RES_BR_ERROR_BARCODE_TYPE;
                    break;
                    case SC_2D_EIMGTYPE:
                        barcode_event_ind.cause = (kal_uint8)MED_RES_BR_IMAGE_ERROR;
                    break;
                }            

            #if defined(AF_SUPPORT)
                camera_operation_setting((kal_uint8) CAM_AF_KEY, (kal_uint16) CAM_AF_RELEASE);
            #endif
                stop_camera_capture_barcode_process();
                cam_release_memory();
                img_release_memory();
                CAM_FREE_BARCODE_BUFFER();
                cam_send_barcode_decode_done_ind(&barcode_event_ind);
                sc2dDecoder_Clean(psc2dBcd);
                scFree2dBarcode(&psc2dBcd);	
                CAM_ENTER_STATE(CAM_READY);
                return;
            }
        }
    #endif /* __MTK_TARGET__ */

    }
    else
    {
        ASSERT(0);
    }
}
#endif /* defined(BARCODE_DECODER_GMEDIA_DM) ||defined(BARCODE_DECODER_GMEDIA_QRDM)*/

#endif
#else
#error "no such combination"
#endif

#if defined(BCR_SUPPORT)
/*****************************************************************************
 * FUNCTION
 *  cam_bcr_set_raw_req_hdlr 
 * DESCRIPTION
 *  This function is to handle set recognizing data mesg.
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_set_raw_req_hdlr (ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_bcr_set_raw_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    req_p = (media_cam_bcr_set_raw_req_struct*) ilm_ptr->local_para_ptr;

    cam_context_p->barcode_buffer_address = (kal_uint32) req_p->raw_buffer;
    cam_context_p->barcode_buffer_width = req_p->image_width;
    cam_context_p->barcode_buffer_height = req_p->image_height;
    cam_context_p->media_mode = MED_MODE_ARRAY;

    cam_set_result(MED_RES_OK);
    CAM_ENTER_STATE(CAM_BCR_READY);
    CAM_SET_EVENT(CAM_EVT_SET_PARAM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_recog_result_ind_hdlr
 * DESCRIPTION
 *  This function is to handle recognizing result indication 
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_recog_result_ind_hdlr(ilm_struct* ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_v_cam_bcr_recog_result_ind_struct* req_p;
    media_cam_bcr_recog_result_ind_struct recog_result_ind;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_BCR_RECOGNIZING))
    {
        req_p = (media_v_cam_bcr_recog_result_ind_struct* ) ilm_ptr->local_para_ptr;

        if (req_p->result == MED_RES_OK)
        {
            recog_result_ind.result = MED_RES_OK;
            recog_result_ind.recog_number = req_p->recog_number;
            recog_result_ind.recog_info = (media_cam_bcr_recog_info_struct*)req_p->recog_info;
        }
        else
        {
            recog_result_ind.result = MED_RES_FAIL;
            recog_result_ind.recog_number = 0;
            recog_result_ind.recog_info = NULL;
        }

        cam_send_bcr_recog_done_ind(&recog_result_ind);

        if (cam_context_p->media_mode == MED_MODE_ARRAY)
        {
            CAM_ENTER_STATE(CAM_IDLE);
            cam_context_p->barcode_buffer_address = NULL;
        }
        else
        {
            CAM_ENTER_STATE(CAM_READY);
        }
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_recog_req_hdlr
 * DESCRIPTION
 *  This function is to handle start recognizing request
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_recog_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_bcr_recog_req_struct *req_p;
    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_BCR_READY))
    {
        req_p = (media_cam_bcr_recog_req_struct*) ilm_ptr->local_para_ptr;
        // Send to MED_V
        cam_send_bcr_v_recog_req(req_p->mode);
        // enter entering recognizing state and wait indication
        CAM_ENTER_STATE(CAM_BCR_ENTERING_RECOGNIZING);
    }
    else
    {
        ASSERT(0);
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_capture_req_hdlr
 * DESCRIPTION
 *  This function is to handle capture raw data request
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_capture_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/
    media_cam_bcr_capture_req_struct *req_p;

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    req_p = (media_cam_bcr_capture_req_struct*) ilm_ptr->local_para_ptr;

    if (CAM_IN_STATE(CAM_PREVIEW))
    {
        CAM_ENTER_STATE(CAM_BCR_READY);

        /* in case user forget free memory */
        CAM_FREE_CAPTURE_BUFFER();

        /* stop prevew before capture */
    #ifdef __MTK_TARGET__
        exit_camera_preview_process();
    #endif

        /* release preview related memory */
        cam_release_memory();

        cam_context_p->media_mode = MED_MODE_BUFFER;
        capture_mem_param.target_width = cam_context_p->barcode_buffer_width = req_p->image_width;
        capture_mem_param.target_height = cam_context_p->barcode_buffer_height = req_p->image_height;

        capture_mem_param.intmem_start_address = cam_context_p->intmem_start_address =
            (kal_uint32) med_alloc_int_mem(cam_capture_mem[0]);
        capture_mem_param.intmem_size = cam_context_p->intmem_size = (kal_uint32) cam_capture_mem[0];
        capture_mem_param.extmem_start_address = 0;
        capture_mem_param.extmem_size = 0;
        capture_mem_param.imgdma_buffer_size = cam_context_p->barcode_buffer_size = req_p->image_width * req_p->image_height * 2;
        capture_mem_param.imgdma_buffer_address = cam_context_p->barcode_buffer_address =
            (kal_uint32) med_alloc_ext_mem(capture_mem_param.imgdma_buffer_size);
        capture_mem_param.block_mode = 0;
        /* for lcd if */
        capture_mem_param.dest_buffer_size = 0;
        capture_mem_param.dest_buffer_address = NULL;
        capture_mem_param.roi_offset_x = cam_context_p->roi_offset_x;
        capture_mem_param.roi_offset_y = cam_context_p->roi_offset_y;
        capture_mem_param.roi_width = req_p->image_width;
        capture_mem_param.roi_height = req_p->image_height;
        capture_mem_param.update_layer = cam_context_p->update_layer;
        capture_mem_param.hw_update_layer = cam_context_p->hw_update_layer;

    #if MT6238_SERIES
        capture_mem_param.yuv_target_width = req_p->image_width;
        capture_mem_param.yuv_target_height = req_p->image_height;
        capture_mem_param.yuv_buffer_size = req_p->image_width*req_p->image_height*3/2;
        capture_mem_param.yuv_output_enable_mode = KAL_FALSE;

        /* IPP Setting */
        capture_mem_param.trigger_lcd = KAL_FALSE;
        capture_mem_param.overlay_frame_mode = KAL_FALSE;
        capture_mem_param.overlay_color_depth = 0;
        capture_mem_param.overlay_frame_source_key = 0;
        capture_mem_param.overlay_frame_width = 0;
        capture_mem_param.overlay_frame_height = 0;
        capture_mem_param.overlay_frame_buffer_address = 0;
        capture_mem_param.image_pitch_mode = KAL_FALSE;
        capture_mem_param.image_data_format = 0;
        capture_mem_param.image_bg_image_width = 0;
        /* Display Setting */
        capture_mem_param.image_clip_mode = KAL_FALSE;
        capture_mem_param.image_clip_left = 0;
        capture_mem_param.image_clip_right = 0;
        capture_mem_param.image_clip_top = 0;
        capture_mem_param.image_clip_bottom= 0;
        /* LCD Setting */
        capture_mem_param.memory_data_format = 0;
        capture_mem_param.lcd_id = cam_context_p->lcd_id;
        capture_mem_param.rot_angle = IMG_ROT_ANGLE_0;
    #endif /* MT6238_SERIES */
        /* capture */

        *req_p->capture_buffer_p = (void*)cam_context_p->barcode_buffer_address;


    #ifdef __MTK_TARGET__

        MED_CAM_GET_START_TIME(CAM_CAPTURE_JPEG_DURATION);
        MED_CAM_START_LOGGING("CPM");
        camera_capture_mem_process(&capture_mem_param);
        MED_CAM_STOP_LOGGING("CPM");
        MED_CAM_GET_STOP_TIME_AND_PRINT_TRACE(CAM_CAPTURE_MEM_DURATION);

    #endif

        /* free internal mem for capture */
        CAM_FREE_INT_BUFFER();
    }
    else
    {
        ASSERT(0);
    }

    CAM_SET_EVENT(CAM_EVT_CAPTURE_BARCODE);
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_clear_raw_data_req_hdlr
 * DESCRIPTION
 *  This function is to handle clear raw data request
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_clear_raw_data_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    CAM_FREE_BARCODE_BUFFER();
    if (cam_context_p->media_mode != MED_MODE_ARRAY)
    {
        CAM_ENTER_STATE(CAM_READY);
    }
    CAM_SET_EVENT(CAM_EVT_SET_PARAM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_clear_recog_req_hdlr
 * DESCRIPTION
 *  This function is to handle clear recognition data request
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_clear_recog_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    ASSERT(cam_context_p->state != CAM_BCR_RECOGNIZING);  
    cam_send_bcr_v_clear_data_req();
   
    CAM_SET_EVENT(CAM_EVT_SET_PARAM);
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_abort_recognize_req_hdlr
 * DESCRIPTION
 *  This function is to handle abort recognizing request
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_abort_recog_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if(CAM_IN_STATE(CAM_BCR_RECOGNIZING))
    {
        cam_send_bcr_v_abort_recog_req();   
        CAM_ENTER_STATE(CAM_BCR_ENTERING_ABORTING);
    }
    else
    {
        CAM_SET_EVENT(CAM_EVT_SET_PARAM);
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_stop_req_hdlr
 * DESCRIPTION
 *  This function is to stop preview
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_stop_req_hdlr(ilm_struct *ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    cam_context_p->src_mod = ilm_ptr->src_mod_id;

    if (CAM_IN_STATE(CAM_PREVIEW))
    {
    #ifdef __MTK_TARGET__
        exit_camera_preview_process();
    #endif
        cam_release_memory();
        CAM_FREE_BARCODE_BUFFER();
        CAM_ENTER_STATE(CAM_READY);
    }
    else if (CAM_IN_STATE(CAM_BCR_READY))
    {
        CAM_FREE_BARCODE_BUFFER();
        CAM_ENTER_STATE(CAM_READY);
    }
    else
    {
        ASSERT(0);
    }

    CAM_SET_EVENT(CAM_EVT_STOP);
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_recog_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle recognition confirm mesg from media_v
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_recog_cnf_hdlr(ilm_struct* ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_BCR_ENTERING_RECOGNIZING))
    {
        CAM_ENTER_STATE(CAM_BCR_RECOGNIZING);
        CAM_SET_EVENT(CAM_EVT_SET_PARAM);       
    }
}


/*****************************************************************************
 * FUNCTION
 *  cam_bcr_abort_cnf_hdlr
 * DESCRIPTION
 *  This function is to handle abort bcr recognizing indication
 * PARAMETERS
 *  ilm_ptr     [?]
 * RETURNS
 *  void
 *****************************************************************************/
void cam_bcr_abort_cnf_hdlr(ilm_struct* ilm_ptr)
{
    /*----------------------------------------------------------------*/
    /* Local Variables                                                */
    /*----------------------------------------------------------------*/

    /*----------------------------------------------------------------*/
    /* Code Body                                                      */
    /*----------------------------------------------------------------*/
    if (CAM_IN_STATE(CAM_BCR_ENTERING_ABORTING))
    {
        if (cam_context_p->media_mode == MED_MODE_ARRAY)
        {
            CAM_ENTER_STATE(CAM_IDLE);
            cam_context_p->barcode_buffer_address = NULL;
        }
        else
        {
            CAM_ENTER_STATE(CAM_BCR_READY);
        }
        CAM_SET_EVENT(CAM_EVT_SET_PARAM);       
    }
}

#endif /* defined(BCR_SUPPORT) */
#endif /* __MED_CAM_MOD__ */

#endif /* MED_NOT_PRESENT */

